커스텀 훅으로 로직 재사용하기
커스텀 훅으로 로직 재사용하기
같은 로직이 여러 컴포넌트에 반복되면 코드가 지저분해지기 쉬워요. React는 그런 반복 로직을 커스텀 훅(custom Hook) 으로 뽑아내서 재사용할 수 있게 해줘요. 커스텀 훅은 use로 시작하는 이름의 일반 JavaScript 함수로, 안에서 다른 훅을 호출할 수 있어요. 이름 규칙과 주의할 점, 그리고 언제 쓰면 좋은지를 정리할게요.
컴포넌트에서 커스텀 훅 뽑아내기
브라우저의 online·offline 이벤트를 구독해서 연결 상태를 갱신하는 코드가 있다고 해볼게요. 만약 useState나 useEffect처럼 내장된 useOnlineStatus 훅이 있다면 컴포넌트들이 훨씬 간단해질 거예요.
그런 내장 훅은 없지만, 직접 만들 수 있어요. useOnlineStatus라는 함수를 선언하고 앞서 컴포넌트들에 있던 중복 코드를 전부 그 함수로 옮기면 돼요.
function useOnlineStatus() {
const [isOnline, setIsOnline] = useState(true);
useEffect(() => {
// online/offline 이벤트 구독 로직
}, []);
return isOnline;
}
훅 이름은 항상 use로 시작
getColor() 함수가 컴포넌트 안에서 호출되면, 그 이름이 use로 시작하지 않으므로 그 안에 React 상태가 들어있지 않다고 확신할 수 있어요. 반면 useOnlineStatus() 같은 호출은 안에서 다른 훅을 호출할 가능성이 높아요. 이 규칙 덕에 코드만 봐도 어디에 상태가 있는지 가늠할 수 있어요.
커스텀 훅은 "상태를 가진 로직"을 공유하지 상태 자체는 공유하지 않아요
앞선 예시에서 네트워크를 켜고 끌 때 두 컴포넌트가 함께 갱신됐어요. 그런데 그것이 두 컴포넌트가 단일 isOnline 상태 변수를 공유한다는 뜻은 아니에요. 실제로는 완전히 독립적인 상태 변수와 이펙트 두 쌍이, 같은 외부 값(네트워크가 켜져 있는가)으로 동기화되다 보니 같은 값을 같게 가진 거예요.
커스텀 훅은 상태를 가진 로직을 공유하지만 상태 자체는 공유하지 않아요. 같은 훅을 호출하더라도 각 호출은 서로 완전히 독립적이에요.
훅 사이에 반응형 값 전달하기
컴포넌트가 재렌더링될 때마다 매번 최신 roomId와 serverUrl을 훅에 전달할 수 있어요. 그 값들이 재렌더링 후 달라지면 Effect가 다시 연결되죠. 이벤트 핸들러도 커스텀 훅에 전달할 수 있는데, 그러면 사용하는 쪽에서 useChatRoom이 내부에서 어떻게 동작하는지 몰라도 돼요. 어떤 컴포넌트에든 그 훅을 붙이고 어떤 옵션이든 넘기면 똑같이 동작해요. 이것이 커스텀 훅의 힘이에요.
커스텀 훅을 언제 쓸까
커스텀 훅을 추출하면 데이터 흐름이 명시적이 돼요. url을 넣으면 data가 나오는 useData 같은 훅처럼요. Effect를 훅 안에 "숨김"으로써, 다른 사람이 컴포넌트에 불필요한 의존성을 추가하는 것도 막을 수 있어요.
요약
- 커스텀 훅은 컴포넌트 간 로직을 공유하게 해줘요.
- 커스텀 훅 이름은
use로 시작하고 그 뒤에 대문자로 이어져야 해요. - 커스텀 훅은 상태를 가진 로직만 공유하고 상태 자체는 공유하지 않아요.
- 한 훅에서 다른 훅으로 반응형 값을 전달할 수 있고, 그 값은 최신으로 유지돼요.
- 모든 훅은 컴포넌트가 재렌더링될 때마다 다시 실행돼요.