개발/Javascript & Typescript

[React] useEffect vs useLayoutEffect - 언제 어떤 걸 써야 할까?

devhooney 2025. 7. 8. 08:34
728x90

React에서 컴포넌트를 만들다 보면 useEffect와 useLayoutEffect라는 두 훅(Hook)을 마주하게 된다. 이름은 비슷하지만 실행 타이밍과 용도, 그리고 렌더링 성능에 미치는 영향까지 완전히 다르다.

이번 포스팅에서는 이 둘의 차이점, 실행 순서, 사용 시 주의점, 그리고 실전 예제까지 한 번에 정리해본다.

 

 

 

 

📌 핵심 요약

항목 useEffect useLayoutEffect
실행 시점 화면 그린 (비동기) 화면 그리기 직전 (동기)
렌더 차단 여부 ❌ 렌더 차단 안 함 ✅ 렌더 차단함
목적 API 호출, 로깅 등 비 UI 작업 DOM 측정, 스타일 조정 등 UI 관련 작업
성능 영향 렌더링 후 실행 → 퍼포먼스에 유리 렌더링 전에 실행 → 렌더 지연 가능성
SSR(Server Side Rendering) SSR 안전 권장되지 않음 (경고 발생)

 

 

 

🧪 실행 타이밍 흐름

[Render Phase]
 → 브라우저가 실제로 DOM을 그리기 전

[Commit Phase]
 → DOM 반영 완료 → 그 다음 순서:

1. useLayoutEffect (즉시 실행)
2. 브라우저 화면 그리기 (Paint)
3. useEffect (비동기 실행)

 

 

즉, useLayoutEffect는 브라우저가 DOM을 그리기 전에 실행되고, useEffect는 브라우저가 화면을 그린 후 실행된다.

 


 

 

🧬 실전 예제: 차이 확인하기

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

function Example() {
  const [value, setValue] = useState(0);

  useLayoutEffect(() => {
    console.log('🟨 useLayoutEffect 실행');
    setValue(100); // 동기적 실행
  }, []);

  useEffect(() => {
    console.log('🟩 useEffect 실행');
    setValue(200); // 비동기적 실행
  }, []);

  console.log('🔄 컴포넌트 렌더링');

  return <div>{value}</div>;
}

 

 

🧾 로그 출력 순서:

🔄 컴포넌트 렌더링
🟨 useLayoutEffect 실행
🟩 useEffect 실행

 

useLayoutEffect는 렌더링을 멈추고 바로 실행됨 → 동기적
useEffect는 렌더링 후 브라우저가 그린 다음 실행됨 → 비동기

 

 

 

728x90

 

 

 


 

 

✅ 언제 useLayoutEffect를 써야 할까?
useLayoutEffect는 정말 특별한 경우에만 써야 한다. 대표적인 예시는 다음과 같다:

📏 DOM 측정

useLayoutEffect(() => {
  const height = elementRef.current.offsetHeight;
  setHeight(height);
}, []);

 

🎯 레이아웃 "깜빡임" 방지
스타일 수정, 애니메이션, 포지션 조정 등 "렌더 후 스타일이 바뀌면 안 되는 상황" 에서 사용

⚠️ 주의할 점
useLayoutEffect는 렌더링을 블로킹하므로, 남용 시 성능 저하 발생
SSR 환경에선 useLayoutEffect가 경고를 발생시킬 수 있음 (브라우저가 없기 때문에)
기본적으로는 useEffect를 사용하고, 정말 필요한 경우에만 useLayoutEffect로 바꿔야 한다

 

 

 


 

 

 

🎯 결론: 정리표

상황 어떤 Hook? 이유
API 호출, 로깅, 타이머 등록 useEffect 화면 그린 후 실행돼도 상관없음
DOM 위치, 크기 측정 useLayoutEffect 브라우저가 그리기 전에 정확한 정보 필요
CSS 기반 애니메이션 조정 useLayoutEffect 레이아웃 깜빡임 방지
성능이 중요한 경우 useEffect 렌더링 블로킹 방지
서버사이드 렌더링 환경 useEffect useLayoutEffect는 경고 발생 가능

 

 

 

 

 

 

 

 

 

728x90