가장 많이 사용하면서도 깊게는 알지 못했던 hook이 바로 useEffect
였다. 그러다 useEffect의 동작원리, 문제점 등에 대해 공부하다보니 자연스럽게 useLayoutEffect라는 훅을 알게 되었다. 둘의 기능은 같지만, 명확한 차이점을 구분할 줄 알아야한다고 생각하여 이렇게 글을 또 남겨본다.
✅ 공식문서
: 이 함수의 시그니처는 useEffect
와 동일하긴 한데, 모든 DOM 변경 후에 동기적으로 발생합니다. 이것은 DOM에서 레이아웃을 읽고 동기적으로 리렌더링하는 경우에 사용하세요.
useLayoutEffect
의 내부에 예정된 갱신은 브라우저가 화면을 그리기 이전 시점에 동기적으로 수행될 것입니다.
단, 공식 문서에서는 보통의 경우는 useEffect를 쓰되, 만약 사용자가 알아차리는 DOM 변경을 하게 될 경우는 useLayoutEffect를 쓰라고 언급하고 있다.
✅ useEffect와 똑같은 형태
useLayoutEffect(() => {
effect
return () => {
cleanup
};
}, [input])
useEffect를 사용할 경우 DOM의 레이아웃 배치와 페인트가 끝난 후에 이펙트 함수를 호출한다.
다시말해 컴포넌트들이 render
와 paint
된 후에 실행되는 비동적 실행을 하게 된다. 상태값이 이픽트에 의존할 경우 화면의 깜빡임 같은 불편한 사용자 경험을 맞딱드릴 수 있다.
💡 핵심 용어
Render: DOM Tree 를 구성하기 위해 각 엘리먼트의 스타일 속성을 계산하는 과정
Paint: 실제 스크린에 Layout을 표시하고 업데이트하는 과정
useEffect는 클래스형 컴포넌트에서 사용하는 컴포넌트 마운트시 실행되는 componentDidMount
메서드와 같은 역할을 하는 hook이라고 할 수 있다.
하지만, 그렇다고 UseEffect
가 componentDidMount
와 완전히 동일한 것은 아니다. 가장 큰 차이는 DOM이 업데이트 된 직후에 비동기적으로 실행되는지, 동기적으로 실행되는지 일 것이다.
useEffect
의 경우 화면이 렌더링된 후에 실행되지만 비동기적 실행으로 약간의 시간차가 생겨서 화면 깜빡임 같은 현상이 발생하는 것이다.
반면, componentDidMount
는 DOM 업데이트 직후 동기적으로 실행된다. 따라서 초기 렌더링은 사용자에게 노출되지 않고 변경된 렌더링만 사용자에게 보여 깜빡임 현상이 발생하지 않는다.
👉 componentDidMount - React.component 공식문서
👉 React LifeCycle Method
useLayoutEffect
가 화면 깜빡임을 없애주지만 그렇다고 모든 useEffect
대신 useLayoutEffect
를 사용할 필요는 없다.
useEffect
는 화면을 그리는 것을 막지 않고 다 그려진 뒤에 실행되는 것을 보장하는 훅이고, 그런 역할이 정해진 훅이기 때문에, 만약 동기적 Effect
를 발생시키고 싶으면 useLayoutEffect
를 사용하면 해결.
따라서 렌더링할 상태가 이펙트 내에서 초기화되어야 할 경우, 사용자 경험을 위해 useLayoutEffect를 활용하자.
🔗 Reference
👉 What is the real difference between React useEffect and useLayoutEffect?
👉 useLayoutEffect (공식문서)
👉 useLayoutEffect 훅에 대하여
👉 [React] useEffect 와 useLayoutEffect 의 차이는 무엇일까?
👉 리액트 useLayoutEffect 훅으로 화면 깜빡임 없애기
👉 리액트 useLayoutEffect 훅으로 화면 깜빡임 없애기