useLayoutEffect is a version of useEffect that fires before the browser repaints the screen.
공식문서에서 `useLayoutEffect`는 브라우저가 리페인트되기 전에 실행되는 `useEffect`라고 서술합니다
그대로 이해하면 React 컴포넌트가 브라우저에 그려지기전에 `useLayoutEffect`의 로직이 먼저 실행된다는 뜻입니다
이게 정확히 무슨뜻인지 이해하기 전에, 이게 의미가 있는 훅일까요?
브라우저가 리페인트되기 전 / 후가 `useEffect` 로직 실행이랑 무슨 상관일까요?
이를 이해하기 위해서는 리액트의 생명주기를 이해하면 좋습니다
리액트 생명주기는 아래와 같습니다
1. 마운트
- lazy 초기화 실행
- useState등에서 lazy 초기화 함수가 실행됩니다
2. 업데이트
- 렌더링: 컴포넌트가 렌더링 / 리-렌더링됩니다
- DOM 업데이트: 리액트가 버츄얼 돔의 업데이트를 실제 돔에 반영합니다
- 브라우저 페인팅: 브라우저가 페이지를 시각적으로 표현합니다
3. 언마운트
- `useEffect`, `useLayoutEffect`를 모두 클린업합니다
이 생명주기에서 `useEffect`는 어떤 시점에 실행될까요?
이 링크에서 확인해보면 Effects run at the end of a commit after the screen updates. 라고합니다
즉 위의 단계에서는 브라우저 페인팅이 끝난 후가 될것입니다
하지만 이러면 문제가 있습니다
문제를 예시로 보겠습니다
const [tooltipHeight, setTooltipHeight] = useState(0);
useEffect(() => {
const rect = ref.current?.getBoundingClientRect();
if (!rect) return;
const { height } = rect;
setTooltipHeight(height);
}, []);
이 로직은 DOM 요소에 접근하여 높이를 알아낸 후에 그 높이를 툴팁 높이로 반영하는 로직입니다
하지만 앞서 언급했듯이 useEffect는 브라우저 페인팅 후에 효과가 발생합니다
즉, 처음 브라우저가 페인트될때 툴팁의 높이는 `0`이 됩니다, 이후 `useEffect`가 실행되어 적절한 높이가 설정될것입니다
이러면 발생하는 문제는 툴팁이 처음 위치와 이후 위치가 달라 일종의 "깜빡임" 현상이 발생할것입니다
이를 효과적으로 처리하기 위해서 `useLayoutEffect`를 사용할 수 있습니다
다시 `useLayoutEffect`의 정의를 보면, **리페인트 되기 전**이 이제 어떤 의미를 갖는지 더욱 알수있게되었습니다
또한 추가적으로 `useLayoutEffect`는 해당 로직이 완료되기 전까지 브라우저 페인트를 중단합니다
이 특성들을 보면 위의 문제를 해결하는 완벽한 솔루션이 될수있습니다
const [tooltipHeight, setTooltipHeight] = useState(0);
useLayEffect(() => {
const rect = ref.current?.getBoundingClientRect();
if (!rect) return;
const { height } = rect;
setTooltipHeight(height);
}, []);
DOM이 업데이트된 후 `useLayoutEffect`의 로직이 실행되어 툴팁의 적절한 높이를 계산할 것이고, 그것을 반영하여 브라우저가 페인팅될것입니다
'React' 카테고리의 다른 글
[React] 헤드리스 컴포넌트란 무엇일까 (1) | 2024.11.07 |
---|---|
[React] Suspense 이해하고 활용하기 03 - Suspense 발전 과정 (1) | 2024.10.02 |
[React] Suspense 이해하고 활용하기 02 - Promise를 던지는 방법, use 훅 (2) | 2024.09.26 |
[React] 공통 컴포넌트를 설계할 때 고려할 점 (2) | 2024.09.21 |
[React] React Query 알아보기 01 - 왜 React Query를 사용해야하는지 (0) | 2024.09.18 |