리액트

useLayoutEffect 훅이란?

파쏭쏭계란빡 2024. 2. 5. 11:28

useLayoutEffect는 React에서 제공하는 Hook 중 하나로, 주로 DOM의 레이아웃을 읽거나 변경할 때 사용됩니다.
useLayoutEffect는 브라우저가 화면을 그리기 전에 실행되므로, DOM을 직접 조작하거나 레이아웃의 측정을 수행하는 경우에 적합합니다.

useLayoutEffect의 실행 시점

컴포넌트 렌더링 이후

  • 컴포넌트의 렌더링 결과가 DOM에 적용된 직후에 실행됩니다.
  • 이 때문에 useLayoutEffect 내부에서 DOM을 읽거나 변경하는 작업을 수행하면,
  • 이러한 작업들이 화면에 반영되기 전에 완료됩니다.

브라우저의 화면 갱신 전

  • React는 useLayoutEffect가 완료될 때까지 화면의 갱신을 지연시킵니다.
  • 이는 useLayoutEffect 내부에서 수행하는 작업이 화면에 반영되기 전에 완료되어야 한다는 것을 의미합니다.

컴포넌트 제거 시

  • useLayoutEffect 내에서 반환하는 클린업(cleanup) 함수는 컴포넌트가 제거될 때 실행됩니다.
  • 이는 주로 이벤트 리스너 제거, 구독 취소 등의 정리 작업을 수행하는 데 사용됩니다.

useEffect와 비교했을 때 다른 점?

  • useLayoutEffect는 DOM의 레이아웃을 계산하거나 변경할 필요가 있는 경우에 주로 사용됩니다.
  • useEffect는 레이아웃 계산이 필요 없는 부수 효과(side effects)를 수행할 때 적합하며,
  • 브라우저가 화면을 그린 후에 실행됩니다.
  • 따라서 useEffect는 화면 깜빡임이나 불필요한 렌더링을 방지할 필요가 없는 경우에 더 적합합니다.

사용 예시

페이지에 버튼이 있고, 이 버튼을 클릭하면 팝업이 나타납니다.

이 팝업은 버튼의 위치에 따라 동적으로 위치를 조정해야 합니다.

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

const Popup = ({ anchor }) => {
  const popupRef = useRef();

  useLayoutEffect(() => {
    if (popupRef.current && anchor) {
      const anchorRect = anchor.getBoundingClientRect();
      const popupRect = popupRef.current.getBoundingClientRect();

      const top = anchorRect.bottom;
      const left = anchorRect.left + (anchorRect.width / 2) - (popupRect.width / 2);

      popupRef.current.style.top = `${top}px`;
      popupRef.current.style.left = `${left}px`;
    }
  }, [anchor]);

  return <div ref={popupRef} className="popup">I'm a Popup</div>;
};

const App = () => {
  const [showPopup, setShowPopup] = useState(false);
  const buttonRef = useRef();

  return (
    <div>
      <button ref={buttonRef} onClick={() => setShowPopup(!showPopup)}>
        Toggle Popup
      </button>
      {showPopup && <Popup anchor={buttonRef.current} />}
    </div>
  );
};

export default App;