Developer/React

useEffect와 useLayoutEffect의 차이 예제로 쉽게 이해하기

jaddong 2023. 1. 13. 00:01
320x100

React로 개발하는 사람들에게는 useEffect는 아주 익숙한 Hook이다.

 

페이지 뿌려줄 data를 불러오기 위해 api call해서 data set하기도 하고

useEffect(() => {
    const getData = async () => {
      const res = await getData();
      setData(res);
    };
    getData();
  }, []);

 

 

store에 있는 값을 체크해 페이지 이동을 하기도 하고

useEffect(() => {
    if (!storeValue) {
       history.goBack();
    }
  }, []);

 

처음 페이지가 떴을 때 스크롤의 위치를 셋팅하기도 한다.

  useEffect(() => {
    window.scrollTo({
      top: 0,
      behavior: "auto",
    });
  }, []);

 

 

 

그런데  useEffect를 useLayoutEffect바꿔서 사용해도 우리 눈에는 페이지가 똑같이 보이는데 무엇이 다른걸까?

 

우선 그 차이를 알기 위해서는 React에서 render와 paint개념을 알아야한다.

  • render : DOM Tree 를 구성하기 위해 각 엘리먼트의 스타일 속성을 계산하는 과정
  • paint : 실제 스크린에 Layout을 표시하고 업데이트하는 과정

render는 paint전에 DOM Tree를 구성하고 계산하는 과정. 즉, paint의 준비 단계라고 볼 수 있겠다.

그렇다면 당연히 순서는 render(준비) -> paint(화면에서 보임) 순일 것이다.

 

useEffect

우선 useEffect는 아래 이미지처럼

render -> paint -> useEffect 순으로 실행된다.

paint가 되고 우리 눈에 다 보이는 상태에서 useEffect가 실행된다.

 

useEffect 사이클

 

예시가 gif 파일이라 자세히 봐야하는데, value가 업데이트 될 때마다 잠깐 0이었다가 다시 값이 셋팅되는 것을 확인할 수 있다.

숫자가 바로바로 바뀌는 것이 아니라 우리 눈에는 무언가 깜빡이는 것처럼 보인다.

즉, 0으로 paint된 후 useEffect로 다시 value가 업데이트되는 것이다.

 

 

UseLayoutEffect

우선 useEffect는 아래 이미지처럼

render -> UseLayoutEffect -> paint 순으로 실행된다.

useEffect와 달리 훅이 먼저 실행되고 paint되어 우리 눈에 보이게 된다.

 

 

useLayoutEffect 사이클

 

 

useEffect 예시와 달리 value가 업데이트 될 때마다 숫자가 바로바로 깔끔하게 업데이트 되는 것을 확인할 수 있다.

UseLayoutEffect이 paint보다 먼저 실행되어 0이 보이기 전 값을 셋팅하기 때문이다.

 

 

예시 코드 직접 확인하기

 

 

결론

대부분의 경우 useEffect를 사용하지만 경우에 따라 구성 요소가 표시될 때 깜박이는 것을 보고 useLayoutEffect로 전환할 수 있다. 그러나 useLayoutEffect는 동기식이므로 성능이 저하될 수 있어 사용할 때 주의해야한다. 이 메서드 실행이 완료될 때까지 UI가 업데이트되지 않기 때문이다.

useEffect를 쓰되 구성 요소가 표시될 때 깜박이는 것이 유저가 불편할 정도로 눈에 띈다면 useLayoutEffect를 적용해볼 수 있겠다. 그러나 useLayoutEffect 에서 실행되는 메서드가 오래 걸리는 메서드라면 화면에 paint가 바로 일어나지 않아 스크린에서 UI를 빠르게 볼 수 없을 수 있으니 이 사항들을 고려하여 선택 사용하면 좋을 것 같다.

 

 

출처 : What is the real difference between React useEffect and useLayoutEffect?

 

 

 

반응형