useEffect vs useLayoutEffect

zzi99·2022년 3월 19일
0

React 📚

목록 보기
7/7

오늘은 useEffect와 useLayoutEffect의 차이에 대해 공부해보려고 합니다.

일단 2가지 과정에 대해 알아야합니다.

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


사진 출처

useEffect

useEffect 는 컴포넌트들이 render 와 paint 된 후 실행됩니다.
비동기적(asynchronous) 으로 실행됩니다.
paint 된 후 실행되기 때문에, useEffect 내부에 dom 에 영향을 주는 코드가 있을 경우 사용자 입장에서는 화면의 깜빡임을 보게됩니다.


사진 출처

useLayoutEffect

useLayoutEffect 는 컴포넌트들이 render 된 후 실행되며, 그 이후에 paint 가 됩니다.
이 작업은 동기적(synchronous) 으로 실행됩니다.
paint 가 되기전에 실행되기 때문에 dom 을 조작하는 코드가 존재하더라도 사용자는 깜빡임을 경험하지 않습니다.

그러면 언제 useEffect를 쓰고 언제 useLayoutEffect 써야할까?

둘의 차이를 봤을 때는 깜빡임이 없는 useLayoutEffect를 사용하는것이 좋다고 생각했습니다.
그러나 useLayoutEffect는 동기적으로 실행되기때문에 useLayoutEffect가 오래걸릴경우 (useLayoutEffect이 실행되고 painting 작업을 하기 때문에) 사용자가 레이아웃을 보는데까지 시간이 오래걸린다는 단점이 있습니다.

그래서 기본적으로는 useEffect을 사용하는 것이 좋습니다.
예를 들면 데이터 fetch, event handler, state reset

그러면 useEffect만 사용하고 useLayoutEffect는 사용하지않을까?

예시 코드

import { useLayoutEffect, useState } from "react";

const Test = () => {
  const [value, setValue] = useState(0);

  useLayoutEffect(() => {
    if (value === 0) {
      setValue(10 + Math.random() * 200);
    }
  }, [value]);

  console.log("render", value);

  return <button onClick={() => setValue(0)}>value: {value}</button>;
};

export default Test;

useLayoutEffect는 위와 같은 경우에 사용하면 좋습니다.
실제로 테스트를 해봤는데 useLayoutEffect가 훨씬 사용자경험이 좋았습니다.
테스트한 동영상을 gif로 올리려니 별차이가 안나보여서 업로드는 하지못했습니다ㅜ

useLayoutEffect는 DOM이 그려지기 전에 호출이 되므로 렌더링할 상태가 이펙트 내에서 초기화되어야 할 경우, 사용자 경험을 위해 useLayoutEffect를 활용하는것이 좋습니다.
이글 보시면 이해가 더 쉽습니다.

회고 🤔

useLayoutEffect를 적절하게 사용을 하여 사용자에게 더 좋은 경험을 줄 수 있도록 해야겠다고 생각했습니다.
리액트 공식문서를 보니 useEffect를 사용하고 문제가 있을 경우에 useLayoutEffect를 사용하라고 나와있습니다. useEffect와 useLayoutEffect를 어떨때 써야할지 나눠서 작성하긴했지만 또 상황에 맞게 직접해보면서 언제 사용하는게 맞을지 차츰 알아가야할것 같습니다..!

참고

📌 https://medium.com/@jnso5072/react-useeffect-%EC%99%80-uselayouteffect-%EC%9D%98-%EC%B0%A8%EC%9D%B4%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C-e1a13adf1cd5
📌 https://merrily-code.tistory.com/46

0개의 댓글