useEffect 와 useLayoutEffect 의 차이

lovjgb·2022년 9월 8일

Side Effect

  • side effect란 함수가 받은 인자 외에 외부에서 함수의 출력에 영향을 주는 모든 상태 변경을 의미한다
    예를 들어 함수의 내부에서 Math.random(), Date.now()를 사용하여 실행할 때마다 결과가 달라지는 것이 대표적인 side effect이다. 그 외에도 함수 내부에서 인자로 받지 않은 외부의 상태를 참조하거나 API로 서버의 데이터를 가져오는 등의 작업도 side effect에 포함된다.
  • useEffect와 useLayoutEffect 모두 컴포넌트에서 side effect가 있는 작업을 수행할 때 사용할 수 있다.

useEffect

  • useEffect 는 컴포넌트들이 render 와 paint 된 후 실행됩니다. 비동기적(asynchronous) 으로 실행됩니다. paint 된 후 실행되기 때문에, useEffect 내부에 dom 에 영향을 주는 코드가 있을 경우 사용자 입장에서는 화면의 깜빡임을 보게됩니다.
  1. 리액트 앱에서 렌더링이 트리거 됨 (dependency 수정됨)
  2. 리액트가 컴포넌트를 렌더링함
  3. 브라우저가 화면을 새로 그림
  4. useEffect가 백그라운드에서 실행됨
  5. useEffect 안에서 DOM 노드 ref를 조작함
  6. 리렌더링, 이펙트가 DOM을 수정하는 동안 잠시 화면이 빔.
  7. 브라우저가 화면을 새로 그림

useLayoutEffect

  • useLayoutEffect 는 컴포넌트들이 render 된 후 실행되며, 그 이후에 paint 가 됩니다. 이 작업은 동기적(synchronous) 으로 실행됩니다. paint 가 되기전에 실행되기 때문에 dom 을 조작하는 코드가 존재하더라도 사용자는 깜빡임을 경험하지 않습니다.
  1. 리액트 앱에서 렌더링이 트리거 됨 (dependency 수정됨)
  2. 리액트가 컴포넌트를 렌더링함
  3. useLayoutEffect가 실행됨
  4. useLayoutEffect가 끝나기를 기다림
  5. 브라우저가 화면을 새로 그림

차이

  • useEffect는 컴포넌트 렌더링과 브라우저 페인팅이 끝난 후 비동기적으로 실행되며, useLayoutEffect는 컴포넌트 렌더링 후 동기적으로 실행되어 작업이 완료되면 브라우저 페인팅이 시작된다.
  • 따라서 로직이 복잡할 경우 사용자가 레이아웃을 보는데까지 시간이 오래걸린다는 단점이 있어, 기본적으로는 항상 useEffect 만을 사용하는 것을 권장드립니다. 구체적인 예시로는

데이터 fetch
event handler
state reset
등의 작업은 항상 useEffect 를 사용하되,
화면이 깜빡거리는 상황일 때, 예를들어 위와같이 state 이 존재하며, 해당 state 이 조건에 따라 첫 painting 시 다르게 렌더링 되어야 할 때는 useEffect 사용 시 처음에 0이 보여지고 이후에 re-rendering 되며 화면이 깜빡거려지기 때문에 useLayoutEffect 를 사용하는 것이 바람직 합니다.

언제 사용?

  • 브라우저 페인트 전 DOM 조작, 혹은 레이아웃 정보를 읽어야 할 때
  1. 스크롤 위치 확인
  • 렌더링 직후 DOM요소의 값을 읽을 때
  1. 화면이 깜빡이는 상황
  • 예를들어, 바로 b라는 데이터를 보여야 될 때 ->처음에 a가 보여지고 이후에 리랜더링이 되므로 이때 사용해야 한다.
  1. 그 외: ref가 업데이트 되기 전 이전 값 확인

+ 내용

.React 18부터 useEffect에 전달된 함수는 클릭과 같은 개별 사용자 입력의 결과이거나 로 래핑된 업데이트의 결과인 경우 레이아웃 및 페인트 전에 동기적으로 실행됩니다. (전달된 함수가 호출되는 타이밍에만 영향을 미칩니다. useEffect이러한 효과 내에서 예약된 업데이트는 여전히 지연e됨)

https://ko.reactjs.org/docs/hooks-reference.html#useeffect

참고 링크
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://woojeongmin.com/2022/study-log/useeffect-uselayouteffect/

profile
lovjgb

0개의 댓글