React 공식문서 스터디

useLayoutEffect

려낭 2024. 6. 11. 21:59

useLayoutEffect란?

 

새로운 글을 클릭하거나 메뉴를 열 때 페이지가 변하는 것을 주목했는가? 이것은 웹 개발자들이 "렌더링"이라고 하는 프로세스에 의해 가능해진다. 이 프로세스는 웹 페이지의 내용을 업데이트 하고 새로운 정보를 보여주는 역할을 한다.

 

여기서 useLayoutEffect라는 것이 나온다. 이것은 React라는 프레임워크에서 사용되는 특별한 기능 중 하나이다. useLayoutEffect는 렌더링이 일어나기 전에 특정 작업을 수행하는 데 사용된다.

 

간단히 말해서 useLayoutEffect는 페이지가 업데이트 되기 전에 어떤 일을 처리할 수 있는 것으로 일종의 준비작업 이라고 할 수 있다.

페이지가 업데이트 되기 전에 필요한 작업들을 처리해 놓는 것이다.

 


 

참조

 

브라우저가 화면을 다시 그리기 전에 useLayoutEffect를 호출하여 레이아웃을 측정한다.

import { useState, useRef, useLayoutEffect } from 'react';

function Tooltip() {
  const ref = useRef(null);
  const [tooltipHeight, setTooltipHeight] = useState(0);

  useLayoutEffect(() => {
    const { height } = ref.current.getBoundingClientRect();
    setTooltipHeight(height);
  }, []);
  // ...

 

 

매개변수

 

setup: Effect의 로직이 포함된 함수이다. 셋업 함수는 선택적으로 클린업 함수를 반환할 수 있다. 컴포넌트가 DOM에 추가되기 전에 React는 셋업 함수를 실행한다. 변경된 의존성으로 다시 렌더링할 때 마다 React는 (클린업 함수를 정의한 경우) 먼저 이전 값으로 클린업 함수를 실행한 다음, 새 값으로 셋업 함수를 실행합니다. 컴포넌가  DOM에서 제거되기 전에 React는 클린업 함수를 한번 더 실행한다.

 

선택적 dependencies : setup 코드 내에서 참조된 모든 반응형 값의 목록이다. 반응형 값에는 props,state,컴포넌트 본문 내부에서 직접 선언된 모든 변수와 함수가 포함된다. 린터가 React용으로 설정된 경우, 모든 반응형 값이 의존성으로 올바르게 지정되었는지 확인한다. 의존성 목록은 일정한 수의 항목을 가져야 하며, [dep1, dep2, dep3] 와 같이 인라인으로 작성해야 한다. React는 Object.js 비교를 사용하여 각 의존성을 이전 값과 비교한다. 이 인수를 생략하면 컴포넌트를 다시 렌더링 할 때 마다 Effect가 다시 실행된다.

 

반환값

 

useLayoutEffect는 undefined를 반환한다.

 

주의사항

 

useLayoutEffect는 훅이므로 컴포넌트의 최상위 레벨 또는 자체 훅에서만 호출할 수 있다. 반복문이나 조건문 내부에서는 호출할 수 없다. 필요하다면 컴포넌트를 추출하고 Effect를 그곳으로 이동해라.

 

Strict Mode가 켜져 있으면 React는 첫번째 실제 셋업 전에 개발 전용 셋업+=클린업 사이클을 한번 더 실행한다. 이는 클린업 로직이 셋업 로직을 미러링 하고  설정이 수행중인 모든 작업을 중지하거나 취소하는지 확인하는 스트레스 테스트이다. 문제가 발생하면 클린업 함수를 구현해라.

 

의존성 중 일부가 컴포넌트 내부에 정의된 객체 또는 함수인 경우, Effect가 필요 이상으로 자주 다시 실행될 위험이 있다. 이 문제를 해결하려면 불필요한 객체 및 함수 의존성을 제거해라. 또한 Effect 외부에서 state업데이트와 비반응형 로직을 추출할 수도 있다.

 

Effects 는 클라이언트에서만 실행된다. 서버 렌더링 중에는 실행되지 않는다.

 

useLayoutEffect 내부의 코드와 여기에서 예약된 모든 state 업데이트는 브라우저가 화면을 다시 그리는 것을 차단한다. 과도하게 사용하면 앱이 느려진다. 가급적이면 useEffect를 사용해라.

 

사용법

 

브라우저에서 화면을 다시 그리기 전 레이아웃 측정하기

 

대부분의 컴포넌트는 무엇을 렌더링할지 결정하기 위해 화면에서의 위치와 크기를 알 필요가 없다. 일부 JSX만 반환하기 때문이다. 그런 다음 브라우저는 해당 컴포넌트의 레이아웃(위치 및 크기)을 계산하고 화면을 다시 그린다.

 

때론 그것만으로는 충분하지 않을 수 있다. 마우스 오버 시 요소 옆에 툴팁을 표시하는 것을 상상해봐라. 공간이 충분하면 툴팁이 요소 위에 표시되어야 하지만, 공간이 충분하지 않으면 아래에 표시되어야 한다. 툴팁을 올바른 최종 위치에 렌더링하려면 툴팁의 높이(즉, 상단에 표시하기에 충분한지 여부)를 알아야 한다.

 

이렇게 하려면 두 번의 패스로 렌더링해야 한다.

 

1.툴팁을 원하는 위치에 렌더링한다(위치가 잘못된 경우에도)

2.높이를 측정하고 툴팁을 배치할 위치를 정한다.

3.올바른 위치에 툴팁을 다시 렌더링한다.

 

이 모든 작업은 브라우저가 화면을 다시 그리기 전에 useLayoutEffect를 호출하여 레이아웃 측정을 수행한다.

 

function Tooltip() {
  const ref = useRef(null);
  const [tooltipHeight, setTooltipHeight] = useState(0); // 아직 실제 높이를 모릅니다.

  useLayoutEffect(() => {
    const { height } = ref.current.getBoundingClientRect();
    setTooltipHeight(height); // 실제 높이를 알았으니 다시 렌더링합니다.
  }, []);

  // ...아래에 올 렌더링 로

 

작동 방식을 단계별로 알아보자.

 

1.Tooltip은 초기화된 값인 tooltipHeight = 0 으로 렌더링된다.(따라서 툴팁의 위치는 잘못될 수 있다.)

2.React가 이 툴팁을 DOM에 배치하고 useLayoutEffect 안의 코드를 실행한다.

3.useLayoutEffect가 툴팁의 높이를 계산하고 바로 다시 렌더링시킨다.

4.Tooltip이 실제 tooltipHeight로 렌더링된다.

5.React가 DOM에서 이를 업데이트하고 브라우저가 툴팁을 표시한다.

'React 공식문서 스터디' 카테고리의 다른 글

useMemo (1)  (0) 2024.06.17
useEffect, useLayoutEffect 발표자료  (0) 2024.06.14
useEffect (3)  (0) 2024.06.10
useEffect (2)  (1) 2024.06.05
useEffect  (0) 2024.06.04