useLayoutEffect vs useEffect

Khan·2022년 9월 27일
0

TIL

목록 보기
13/19
post-thumbnail

들어가기 전에

React Hooks Flow

React Hooks flow includes :

  • Mount
  • Update (when state changes based on any event)
  • UnMount

Mount

  • Run lazy initializer
  • Render
  • React updates DOM
  • Run Layout Effects
  • Browser paints the screen
  • Runs Effcts

Update : When the user make any event it update the state

  • Render
  • React updates
  • Cleanup LayoutEffects first
  • Run LayoutEffects
  • Browser paints the screen
  • Cleanup the effects first
  • Run Effects

Unmount : Component gets removed from the screen

  • Cleanup LayoutEffects
  • Cleanup Effects

개념설명

Render:

  • DOM Tree 를 구성하기 위해 각 엘리먼트의 스타일 속성을 계산하는 과정

Paint:

  • 실제 스크린에 Layout을 표시하고 업데이트하는 과정

useEffect와 useLayoutEffect의 차이점

useEffectuseLayoutEffect
동기 & 비동기비동기동기
실행순서컴포넌트 렌더링 - 화면 업데이트 - useEffect실행컴포넌트 렌더링 - useLayoutEffect 실행 - 화면 업데이트
사용예시Side Effect(데이터 가져오기, 구독 설정하기, 수동으로 Dom을 수정)렌더링 직후 DOM요소의 값을 읽을 때 유용함(scroll position등)

React 공식문서에 나온 차이점

The signature is identical to useEffect, but it fires synchronously after all DOM mutations. Use this to read layout from the DOM and synchronously re-render. Updates scheduled inside useLayoutEffect will be flushed synchronously, before the browser has a chance to paint.

useLayoutEffect는 useEffect와 동일하지만, useLayoutEffect는 DOM 변경 후에 동기적으로 발생한다. 이를 통해 DOM에서 레이아웃을 읽고 동기적으로 리 랜더링 한다. useLayoutEffect 내에서 스케줄된 업데이트는 브라우저가 Paint하기 전에 동기적으로 실행된다.

But, Prefer the standard useEffect when possible to avoid blocking visual updates.

하지만 시각적 업데이트를 차단하지 않으려면 가능하면 표준 useEffect를 사용해라.

useEffect 문제점


위에서 설명한것 처럼 useEffect는 비동기로 동작한다. 그래서 만약 Render-tree가 생성 후 DOM 노드의 레이아웃이 변경 시 reflow와 repaint가 발생하게 되는데 사용자 입장에서는 화면이 깜빡임이 발생할 수 있다

해결방법

useEffect 실행전 이미 페인팅이 된 요소가 useEffect 실행 이후 위치가 변한다.

useLayoutEffect 실행 이후 페인팅 되기 때문에 useEffect와 다르게 초기위치없이 바로 원하는 위치에 페인팅 된다.

결론

1. 우선 useEffect를 써라
2.동기적인 랜더링, 깜빡임 등에 useLayoutEffect를 제한적으로 고려해봐라
3. 두 훅의 차이점은 브라우저 페인팅 전후에 따른 실행 순서의 차이다.

출처

리액트 공식문서
Learn useLayoutEffect In 5 Minutes

0개의 댓글