최근 바쁜 일상을 지내던 중 동료 개발자분이 useLayoutEffect을 쓰는것을 보고 요놈의 쓰임새가 궁금해서 정리하기로 하였다.
설명에 들어가기전 중요 개념 2가지를 알아야 한다.
- Render: DOM Tree 를 구성하기 위해 각 엘리먼트의 스타일 속성을 계산하는 과정
- Paint: 실제 스크린에 Layout을 표시하고 업데이트하는 과정
useEffect 는 컴포넌트들이 render 와 paint 된 후 실행된다. 비동기적으로 실행됩니다. paint 된 후 실행되기 때문에, useEffect 내부에 dom 에 영향을 주는 코드가 있을 경우 사용자 입장에서는 화면의 깜빡임을 보게됩니다.
useLayoutEffect 는 컴포넌트들이 render 된 후 실행되며, 그 이후에 paint 가 됩니다. 이 작업은 동기적으로 실행됩니다. paint 가 되기전에 실행되기 때문에 dom 을 조작하는 코드가 존재하더라도 사용자는 깜빡임을 경험하지 않습니다.
useLayoutEffect 는 동기적으로 실행되고 내부의 코드가 모두 실행된 후 painting 작업을 거칩니다. 따라서 로직이 복잡할 경우 사용자가 레이아웃을 보는데까지 시간이 오래걸린다는 단점과 성능 저하가 우려되어, 기본적으로는 항상 useEffect 만을 사용하는 것을 권장드립니다.
구체적인 예시로는
- Data fetch
- Event Handler
- State reset
등의 작업은 useEffect를 사용하여야 하고
const Layout = () => {
const [count, setCount] = useState(0);
useLayoutEffect(() => {
if (value === 0) {
setValue(10 + Math.random() * 200);
}
}, [count]);
return (
<button onClick={() => setCount(0)}>
count: {count}
</button>
);
};
위의 코드와 같이 초기 값과 paint된후의 값이 다를때 깜빡임이 일어날수 있어
이럴경우 useLayoutEffect를 사용하는게 바람직하다.