📌 useLayoutEffect()
: 브라우저가 화면을 그리기 전에 실행되는 useEffect
- 브라우저가 화면을 다시 그리기 전에 레이아웃 계산
- DOM이 변경된 후, 브라우저가 화면에 반영하기 전에 실행된다.
👉 레이아웃이나 DOM 관련 조작에 적합
👉 애니메이션 라이브러리 사용
useLayoutEffect(setup, dependencies?)
- 매개변수
- setup
: Effect의 로직이 포함된 함수
- clean-up 함수를 반환할 수도 있다.
- 컴포넌트가 DOM에 추가되기 전에 React는 setup 함수를 실행한다.
- dependencies가 변경되어 다시 렌더링 될 때마다, React는 (cleanup 함수를 제공했다면) 먼저 이전 값으로 cleanup 함수를 실행한 다음, 새로운 값으로 setup 함수를 실행한다.
- dependencies
: setup 함수 내에서 참조된 모든 반응형 값의 목록(의존성 배열)
- 반응형 값에는 props, state, 모든 변수와 함수가 포함된다.
- 의존성 목록에는 일정한 수의 항목이 있어야 하며 [dep1, dep2, dep3]와 같이 작성해야 한다.
- 의존성을 지정하지 않으면, 컴포넌트를 다시 렌더링할 때마다 Effect가 다시 실행된다.
- setup
✨ useLayoutEffect와 useEffect 실행 시점
1. 컴포넌트 렌더링(마운트) 시점
- useLayoutEffect의 이펙트 콜백 함수
- 컴포넌트가 처음으로 렌더링될 때(컴포넌트가 화면에 마운트되는 시점)에 실행
- DOM이 이미 생성되었지만 브라우저가 화면에 그리기(painting)를 완료하기 전 시점
- 컴포넌트가 처음으로 렌더링될 때(컴포넌트가 화면에 마운트되는 시점)에 실행
- useEffect의 이펙트 콜백 함수
- 컴포넌트가 마운트된 후 브라우저가 화면에 내용을 그린 후에 실행
- 이 시점에서의 작업은 이미 화면에 그려진 후에 실행됨
- 컴포넌트가 마운트된 후 브라우저가 화면에 내용을 그린 후에 실행
2. 컴포넌트 리렌더링(업데이트) 시점
- DOM 커밋 시점
- 컴포넌트가 리렌더링될 때, 가상 DOM의 변경 사항이 실제 DOM에 적용되는 순간
- useLayoutEffect의 이펙트의 클린업 함수
- 리렌더링이 발생할 때, 이전의 useLayoutEffect가 정리(cleanup)되는 시점
- 이전 이펙트에서 설정한 DOM 조작이나 다른 부수 효과를 정리
- 리렌더링이 발생할 때, 이전의 useLayoutEffect가 정리(cleanup)되는 시점
- useLayoutEffect의 이펙트 콜백 함수
- 클린업 함수가 실행된 후, 새로운 DOM 변경 사항이 커밋된 직후에 실행
- 이 시점에서 새로운 DOM 조작이 실행됨
- 클린업 함수가 실행된 후, 새로운 DOM 변경 사항이 커밋된 직후에 실행
- useLayoutEffect의 이펙트의 클린업 함수
- 브라우저 페인팅 시점
- 브라우저가 실제로 변경된 내용을 화면에 그리는 순간
- useEffect의 이펙트의 클린업 함수
- 브라우저가 화면에 변화를 그리기 전에, 이전 useEffect에서 설정한 부수 효과를 정리
- useEffect의 이펙트 콜백 함수
- 브라우저가 화면에 변화를 그린 후에 실행
- 이 시점에서 수행되는 작업은 사용자가 이미 업데이트된 내용을 본 후에 실행됨
- 브라우저가 화면에 변화를 그린 후에 실행
- useEffect의 이펙트의 클린업 함수
예제 1. DOM의 너비를 측정하고, 그 값에 따라 스타일을 변경
import React, { useRef, useLayoutEffect, useState } from 'react';
function LayoutEffectExample() {
const divRef = useRef(null); // div 요소를 참조하기 위한 ref 생성
const [width, setWidth] = useState(0); // div의 너비를 상태로 관리
useLayoutEffect(() => {
// DOM이 커밋된 후 바로 실행됨
// 이 시점에 div의 실제 너비를 가져올 수 있음
if (divRef.current) {
setWidth(divRef.current.offsetWidth);
}
}, []); // 빈 배열을 의존성으로 사용하여 마운트 시 한 번만 실행
return (
<div>
<div
ref={divRef}
style={{ width: '50%', backgroundColor: 'lightblue' }}
>
This div is 50% of the container's width
</div>
<p>The width of the above div is: {width}px</p>
</div>
);
}
export default LayoutEffectExample;