Hook은 무조건 최상위 레벨에서만 호출
리액트 함수 컴포넌트에서만 Hook을 호출
// if문의 조건문에서 참인 경우에 useEffect Hook 호출
// name의 값이 빈 문자열이 되면 조건문의 값이 false가 되어 useEffect Hook이 호출되지 않음
function MyComponent(props) {
const [name, setName] = useState('Inje');
if (name !== '') }
useEffect(() => {
...
});
}
...
}
// 결과적으로 렌더링될 때마다 Hook이 같은 순서대로 호출되는 것이 아니라 조건문의 결과에 따라 호출되는 Hook이 달라지므로 잘못된 코드
❕ Hook은 최상위 레벨에서만 호출
Hook의 규칙을 따르도록 강제해주는 것
const memoizedValue = useMemo(
() => {
// 연산량이 높은 작업을 수행하여 결과를 반환
return computeExpensiveValue(의존성 변수1, 의존성 변수2);
},
[의존성 변수1, 의존성 변수2]
);
// useMemo에서 의존성 배열에 넣은 변수들은 create 함수에 파라미터로 전달되지 않음
// useMemo Hook의 원래 의미가 의존성 배열에 있는 변수 중에 하나라도 변하면 create 함수를 다시 호출
// create 함수를 참조하는 모든 변수를 의존성 배열에 넣어주는 것이 맞음
❕ 참고 링크
https://www.npmjs.com/package/eslint-plugin-react-hooks
여러 컴포넌트에서 반복적으로 사용되는 로직을 Hook으로 만들어 재사용
// UserStatus Component, IsOnline status에 따라서 사용자의 상태 온라인인지 아닌지 테스트로 보여주는 Component
import React, { useState, useEffect } from "react";
function UserListItem(props) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ServerAPI.subscribeUserStatus(props.user.id, handleStatusChange);
return () => {
ServerAPI.unsubscribeUserStatus(props.user.id, handleStatusChange);
};
});
return (
<li style={{ color: isOnline ? 'green' : 'black' }}>
{props.user.name}
</li>
);
}
이름이 use로 시작하고 내부에서 다른 Hook을 호출하는 하나의 자바스크립트 함수
// 두 개의 Component에서 중복되는 로직을 추출
// 여기서 useUserStatus Hook의 목적은 사용자의 온라인, 오프라인 상태를 구독하는 것
import import React, { useState, useEffect } from "react";
function useUserStatus(userId) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ServerAPI.subscribeUserStatus(userId, handleStatusChange);
return () => {
ServerAPI.unsubscribeUserStatus(userId, handleStatusChange);
};
});
return isOnline;
}
// useUserStatus Hook의 파라미터로 userId를 받도록 만들고 해당 사용자가 온라인인지 오프라인지 상태를 리턴
❕ Custom Hook의 이름은 꼭 use로 시작
// ChatUserSelector Component
// Selector 태그를 통해 목록에서 사용자를 선택
// 사용자를 선택시 해당 사용자가 온라인인지 아닌지 보여줌
const userList = [
{ id: 1, name: 'Inje' },
{ id: 2, name: 'Mike' },
{ id: 3, name: 'Steve'},
];
function ChatUserSelector(props) {
// useState Hook을 이용해 userId state를 만듬, Id 저장용
// userId는 useUserStatus Hook 파라미터로 들어감
// setUserId 함수를 통해 userId 변경될 때마다
// useUserStatus Hook은 이전에 선택된 사용자를 구독 취소 새로 선택된 사용자를 온라인 여부로 구독
const [userId, setUserId] = useState(1);
const isUserOnline = useUserStatus(userId);
return (
<>
<Circle color={isUserOnline ? 'grren' : 'red' } />
<select
value={useId}
onChange={event => setUserId(Number(event.target.value))}
>
{userList.map(user => (
<option key={user.id} value={user.id}>
{user.name}
</option>
))}
</select>
</>
);
}