Blog

자주 사용하는 리액트 훅 (2)


4 min read

서론#

앞선 글에서는
렌더링과 직접 맞닿아 있는 훅들,

  • useState
  • useEffect
  • useRef

을 중심으로 정리했다.

이 훅들이
"컴포넌트 내부의 동작"을 다룬다면,
이번 글의 훅들은 구조와 범위를 정리하기 시작할 때 등장한다.

이 글에서는 다음 세 가지 훅을 다룬다.

  • useLayoutEffect
  • useContext
  • 커스텀 훅

(4) useLayoutEffect#

useLayoutEffect
useEffect와 비슷해 보이지만,
실행 시점이 다르다.

  • useEffect → 화면이 그려진 이후
  • useLayoutEffect → 화면이 그려지기 직전

이 차이 때문에
useLayoutEffect는 다음과 같은 상황에서 유용하다.

  • DOM 크기 측정이 필요한 경우
  • 레이아웃 계산 결과를 바로 반영해야 하는 경우
  • 화면 깜빡임을 허용할 수 없는 경우
useLayoutEffect(() => {
  const width = ref.current?.offsetWidth;
  setWidth(width);
}, []);

중요한 점은
useLayoutEffect는 렌더링을 막을 수 있다는 점이다.

그래서 이 훅은
더 강력한 effect가 아니라,
정확한 타이밍이 필요한 경우에만 사용하는 훅에 가깝다.

(5) useContext#

useContext
props를 계속 내려보내는 구조가
불편해지기 시작할 때 등장한다.

주로 다음과 같은 상황에서 유용하다.

  • 동일한 범위의 여러 컴포넌트에서 사용되는 상태
  • props로 전달하기에는 경로가 너무 긴 경우
  • 페이지나 특정 영역 안에서만 필요한 공통 상태
const value = useContext(SomeContext);

다만 useContext
전역 상태 관리 도구가 아니다.

  • Provider 범위에 강하게 의존하고
  • 사용처가 늘어날수록 의존성이 코드에 드러나지 않는다

그래서 useContext
"props drilling 제거 도구"라기보다,
상태의 범위가 명확할 때 사용하는 수단에 가깝다.

(6) 커스텀 훅#

커스텀 훅은
새로운 기능을 만드는 것이 아니라,
기존 훅들을 묶어 의미를 부여하는 방식이다.

주로 이런 상황에서 유용했다.

  • 동일한 로직이 여러 컴포넌트에 반복될 때
  • 컴포넌트가 로직으로 복잡해졌을 때
  • UI와 무관한 로직을 분리하고 싶을 때
const useWindowWidth = () => {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener("resize", handleResize);
    return () => window.removeEventListener("resize", handleResize);
  }, []);

  return width;
};

커스텀 훅의 장점은
재사용성보다 가독성과 책임 분리에 있었다.

컴포넌트는 UI에 집중하고,
로직은 훅에 위임할 수 있었다.

8