useLayoutEffect
는 useEffect와 동일한 구조를 가지고 있기 때문에 그 둘의 차이점을 파악해보고자 useEffect에 대해 간단히 정리하고 넘어가자
리액트의 공식문서를 보면 useEffect 훅을 사용할 경우 DOM의 레이아웃 배치와 페인트가 끝난 후 이펙트 함수를 호출한다고 한다. 따라서 상태값이 useEffect에 의존할 경우 이는 불편한 경험을 줄 수 있다.
import { useEffect, useState } from "react";
function App() {
const [age, setAge] = useState(0);
useEffect(() => {
setAge(26);
}, []);
return (
<>
<div className="App">{`제 나이는 ${age}살 입니다.`}</div>
</>
);
}
export default App;
위의 예시를 들어 useEffect에 대해 다시 알아보자
공식문서에서 언급되었듯이 useEffect 훅은 초기 페인트가 끝난 이후에 실행되는데, 이는 이러한 결과를 가져온다.
제 나이는 0살입니다.
를 페인트제 나이는 26살입니다
이러한 수행 과정에서 짧은 순간이지만 사용자는 제 나이는 0살입니다
라는 의도치 않은 뷰를 보게된다. 위처럼 간단한 코드의 경우에는 이러한 문제가 큰 영향을 주진 않지만 실제 서비스에서, 화면이 복잡해짐에 따라서 렌더링에 소요되는 시간이 길어지면 사용자는 의도치 않은 뷰를 꽤 오랜 시간 마주하게 된다.
useLayoutEffect는 이러한 문제를 해결하기 위한 훅이다.
useLayoutEffect는 브라우저가 화면에 DOM을 그리기 전에 실행된다. 따라서 아래의 코드의 실행 순서도 위의 useEffect를 사용했을 때와 차이가 있다.
import { useLayoutEffect, useState } from "react";
function App() {
const [age, setAge] = useState(0);
useLayoutEffect(() => {
setAge(26);
}, []);
return (
<>
<div className="App">{`제 나이는 ${age}살 입니다.`}</div>
</>
);
}
export default App;
제 나이는 26살입니다
를 페인트초기 렌더링에 필요한 state가 effect 훅 내부에서 초기화되어야 하는 경우, useLayoutEffect를 사용하여 원하는 화면을 사용자에게 바로 전달할 수 있다.