Frontend/React

useEffect vs useLayoutEffect

JTB 2025. 10. 27. 21:25

리액트에서 사이드 이펙트를 다루기 위해 자주 사용하는 훅이 useEffectuseLayoutEffect이다. 둘 다 컴포넌트가 마운트된 후 동작하지만, 실행 시점사용 목적이 다르다.

 

1. 기본 개념

실행 시점 특징 주로 사용하는 상황
useEffect 화면 렌더링 후 비동기적으로 실행 데이터 요청, 구독, 이벤트 등록 등, 화면 깜빡임이 크게 문제되지 않는 작업
useLayoutEffect 화면 렌더링 직전 동기적으로 실행 DOM 측정, 레이아웃 조정 등, 화면이 그려지기 전에 처리해야 하는 작업

 

핵심 포인트

  • 둘 다 마운트 후 동작하지만, useLayoutEffect는 화면 그리기 전에 실행되어 레이아웃을 수정해도 깜빡임이 발생하지 않음.
  • useEffect는 화면 렌더링 이후 실행되므로, 화면이 먼저 그려지고 나서 사이드 이펙트가 발생함.

 

2. 사용 사례와 코드 예시

useEffect

주로 ‘비동기 사이드 이펙트’ 처리에 사용하며, 화면 렌더링 후 실행되므로 화면 깜빡임이 문제가 되지 않는 작업에 적합하다.

 

1. 데이터 요청 / API 호출

  • 컴포넌트가 마운트될 때 서버에서 데이터를 가져와 상태를 업데이트
  • 화면 렌더링 후 실행되므로 초기 화면이 바로 그려짐
useEffect(() => {
  fetch("/api/posts")
    .then(res => res.json())
    .then(data => setPosts(data));
}, []);

 

2. 구독 / 이벤트 등록

  • 브라우저 이벤트, WebSocket 구독 등
  • useEffect에서 반환함수로 정리(cleanup) 가능
useEffect(() => {
  const handleResize = () => setWidth(window.innerWidth);
  window.addEventListener("resize", handleResize);
  return () => window.removeEventListener("resize", handleResize);
}, []);

 

3. 로컬 스토리지, 로그 기록, Analytics

  • UI 렌더링에 직접 영향을 주지 않는 작업
  • 화면 깜빡임 없이 안전하게 수행 가능

정리: 화면이 먼저 그려져도 문제 없는 ‘비동기적, 렌더링 비의존적’ 작업 처리용

 

useLayoutEffect

주로 ‘동기 사이드 이펙트’ 처리에 사용하며, 화면이 그려지기 직전에 실행되어 레이아웃, DOM 측정, 스타일 조정 등 렌더링 직전 작업에 적합하다.

1. DOM 크기/위치 측정

  • getBoundingClientRect() 등으로 요소 위치, 크기 측정
  • 화면 깜빡임 없이 즉시 상태에 반영 가능
useLayoutEffect(() => {
  if (boxRef.current) {
    setHeight(boxRef.current.getBoundingClientRect().height);
  }
}, []);

 

2. 스크롤 위치 조정

  • 모달 오픈 시 스크롤을 특정 위치로 이동
  • 화면이 잠깐이라도 잘못 그려지면 UX 문제 발생 → useLayoutEffect 사용

3. 스타일 / 애니메이션 초기 설정

  • 렌더링 전에 DOM 스타일을 변경하거나 트랜지션 초기화
  • 화면 깜빡임 없이 사용자 경험 제공

정리: 화면 렌더링 전에 ‘동기적, 렌더링 의존적’ 작업 처리용