React
[Hook] Custom Hook
Mia_
2023. 1. 23. 21:08
Custom Hooks
: 개발자가 스스로 커스텀한 Hook. 이를 이용해 반복되는 로직을 함수로 뽑아내어 재사용 할 수 있음!
자주 사용되는 케이스
- 여러 URL을 fetch할 때
- 여러 input에 의한 상태 변경
- 위 처럼 반복되는 로직을 동일한 함수에서 작동하게 하고 싶을 때 주로 사용
이용 시 장점
- 상태 관리 로직의 재사용 가능
- 클래스 컴포넌트보다 적은 양의 코드로 동일한 로직이 구현 가능
- 함수형으로 작성하기 때문에 보다 명료함
Custom Hook 사용 규칙
- Custom Hook을 정의할 때 함수 이름 앞에 use를 붙이는 것
- 대개의 경우 프로젝트 내의 hooks 디렉토리에 Custom Hook을 위치 시킴
- Custom Hook을 만들 때 함수는 조건부 함수가 아니여야 함 → 즉, return 하는 값은 조건부여서는 안됨!
- Custom Hook은 useState와 같이 리액트 내장 Hook을 사용하여 작성 할 수 있음 (일반 함수 내부에서 리액트 내장 Hook을 불러 사용할 수 없음)
- 같은 Custom Hook을 사용했다고 해서 두 개의 컴포넌트가 같은 state를 공유하는 것은 아님!
1. Custom Hook을 사용하지 않은 예시
//FriendStatus : 친구가 online인지 offline인지 return하는 컴포넌트
function FriendStatus(props) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}
//FriendListItem : 친구가 online일 때 초록색으로 표시하는 컴포넌트
function FriendListItem(props) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
return (
<li style={{ color: isOnline ? 'green' : 'black' }}>
{props.friend.name}
</li>
);
}
2. Custom Hook 예시
function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
};
});
return isOnline;
}
3. 2 에서 만든 Custom Hook을 이용해 1 을 재작성
function FriendStatus(props) {
const isOnline = useFriendStatus(props.friend.id);
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}
function FriendListItem(props) {
const isOnline = useFriendStatus(props.friend.id);
return (
<li style={{ color: isOnline ? 'green' : 'black' }}>
{props.friend.name}
</li>
);
}