코딩하는라민

[React] useLayoutEffect 는 언제 사용할까? 본문

Core/React

[React] useLayoutEffect 는 언제 사용할까?

코딩하는라민 2023. 4. 16. 16:20
728x90
반응형

[React] useLayoutEffect 는 언제 사용할까?

 

📌 useEffect 이란?

 

 

[React] Hooks - useEffect ( )

[React] Hooks - useEffect ( ) 📌 클래스형 컴포넌트의 생명주기 [React] 라이프사이클(LifeCycle) - React 의 생명주기 [React] 라이프사이클(LifeCycle) - React 의 생명주기 📌 LifeCycle 어떤 프로그램이 실행되고

ramincoding.tistory.com

앞의 포스팅에서 알아본 바와같이 useEffect 는 클래스형 컴포넌트 생명주기의 componentDidMount, componentDidUpdate, componentWillUnmount 훅을 하나의 API 로 합친 것으로 의존성 배열 deps 를 통해 이를 구분할 수 있었다.

 

useEffect(()=>{
    ...
}, [deps])

 

처음 렌더링될 때 한번만 실행하고자 하는 Side Effect 는 useEffect 의 두 번째 인자인 deps 에 빈 배열을 넣어주고, 컴포넌트가 렌더링 될대마다 실행되고자 한다면 이를 비워두면 된다.

 

이렇게 useEfflect 로 전달된 함수는 지연 이벤트 동안 레이아웃 배치를 완료한 후에 발생된다.

즉 렌더링을 마친 후에 useEffect 내의 함수가 비동기적으로 실행되는 것이다.

따라서 구독 이벤트, 구독 취소 이벤트에 useEffect 를 사용한다.

 

하지만 이렇게 모든 Side Effect 들이 지연되어 실행될 수는 없다.

프로젝트를 진행하다보면 렌더 이전에 먼저 실행되어야 할 이벤트들이 생길 수도 있다.

이럴 때는 useEffect 가 아닌 useLayoutEffect 라는 Hook 을 사용하면 된다.

 

📌 useLayoutEffect 이란?

useLayoutEffect 안의 Side Effect 들은 브라우저가 화면을 그리기 이전 시점에 동기적으로 수행된다.

동기적이라는 것은 코드가 위에서 아래로 수행되는 것을 의미한다.

 

useLayoutEffect(()=>{
    ...
}, [deps])

 

useLayoutEffect 는 동기적으로 내부의 코드가 실행되고 나서 화면을 렌더링하기 때문에 웬만하면 복잡한 작업을 수행하지 않는 것이 좋다.

즉 네트워크, 비동기, DOM 접근 등의 Side Effect 는 useLayoutEffect 보다는 useEffect 를 사용하는 것이 좋다.

 

하지만 useEffect 는 컴포넌트들이 렌더링되고 나서 비동기적으로 실행되기 때문에 사용자가 화면의 깜빡임을 느낄 수 있기 때문에 useEffect 도 웬만하면 사용하지 않는 것이 좋긴 하다.

 

📌 useLayoutEffect 를 사용하는 경우

useLayoutEffect 를 사용하는 예시는 아래와 같다.

  • DOM 요소의 크기나 위치를 변경할 때
  • 애니메이션을 시작하거나 중단시킬 때
  • 브라우저의 캔버스에 그래픽 요소를 렌더링할 때

 

예를 들어보면, useLayoutEffect 로 너비가 변경될 때마다 상태를 업데이트해줄 수 있다.

function MyComponent() {
  const refDiv = useRef(null);
  const [divWidth, setDivWidth] = useState(0);  

  useLayoutEffect(() => {
    if (refDiv.current) {
      setDivWidth(ref.current.getBoundingClientRect().width);
    }
  }, []);

  return (
    <div ref={refDiv}>
      <p>이 요소의 너비는 {divWidth}px 입니다.</p>
    </div>
  );
}

useRef 로 div 를 선택해 div 요소가 변경될 때마다 useLayoutEffect 는 실행된다.

getBoundingClientRect 는 지정된 요소의 크기와 위치에 대한 정보를 제공하는 DOM의 메서드로 위의 예시처럼 너비 뿐만 아니라 left, top, right, bottom, x, y, height 등의 객체를 반환한다.
즉 div 의 너비를 계산해서 이것의 너비가 변경될 때마다 상태(divWidth)에 업데이트한다.

 

브라우저는 초기 렌더링 이후에 화면의 크기가 변경될 때 새로운 레이아웃을 계산한다.

useLayoutEffect 은 레이아웃이 계산된 이후에 실행된다.

그러고 나서 브라우저가 렌더링되기 때문에 useEffect 보다 먼저 실행되는 것이다.

 

✏️ 브라우저에 변경이 생긴 경우 이런 순서로 실행된다.

  1. 브라우저의 사이즈가 변경된다 ➡️
  2. 브라우저는 변경된 레이아웃을 계산된다  ➡️
  3. useLayoutEffect 훅이 실행 ➡️
  4. 브라우저가 변경된 레이아웃을 기반으로 뷰를 업데이트하고 렌더링된다 ➡️
  5. useEffect 훅이 실행

 

 

 

📝 나중에 읽어볼 다른 블로그들 메모

useLayoutEffect 관련 글을 보다가 어떤 질문 답변 게시판을 봤는데 답변에 이 두 블로그를 추천해주길래 가져와봤다.

나중에 자세히 읽어보자.

 

 

 

useEffect 완벽 가이드

이펙트는 데이터 흐름의 한 부분입니다.

overreacted.io

 

 

useEffect가 나를 열받게 했다

이번에 새로운 기능을 개발하면서 상태의 변화에 따른 side effect들을 처리해주기 위해 useEffect를 많이 사용하게 됐다. 기능의 생명 주기를 stage라는 단위로 구분했는데, 원래는 페이지 단위로 사

iborymagic.tistory.com

 

 

 

 


참고 : React 공식 문서, chatGPT
  등을 공부하고, 간단하게 정리한 내용입니다. 잘못된 부분이나 문제되는 점이 있으면 댓글 부탁드립니다.

 

728x90
반응형