← 글 목록

notes

useEffect와 useLayoutEffect.

useEffect와 useLayoutEffect의 실행 시점·용도·렌더링 차이 정리.



렌더링 순서

1. React가 DOM 업데이트 (commit)
2. useLayoutEffect 실행  ← 여기 (동기, paint 전)
3. 브라우저 paint (화면에 그림)
4. useEffect 실행       ← 여기 (비동기, paint 후)

그래서 useLayoutEffect는 사용자가 화면을 보기 전에 DOM 관련 작업을 끝낼 수 있습니다.


useEffect — 기본

useEffect(() => {
  // 화면이 이미 그려진 뒤 실행
  fetchData();
  subscribe();
}, [deps]);

쓰는 경우

  • API 호출
  • 이벤트 리스너 등록/해제
  • 타이머, 구독
  • localStorage 읽기/쓰기
  • 화면 깜빡임과 무관한 대부분의 작업

특징

  • paint를 막지 않음 → 메인 스레드 부담 적음
  • 실행이 한 프레임 늦게 보일 수 있음

useLayoutEffect — 레이아웃·DOM 전용

useLayoutEffect(() => {
  // paint 전에 실행 — 사용자는 아직 안 그려진 상태
  const height = ref.current.getBoundingClientRect().height;
  setHeight(height);
}, [deps]);

쓰는 경우

  • getBoundingClientRect(), offsetHeight 등 레이아웃 측정
  • 측정 결과로 스타일/위치를 바로 수정 (툴팁 위치, 애니메이션 시작점)
  • 스크롤 위치 복원
  • 한 프레임 깜빡임(flash) 을 막아야 할 때

특징

  • paint 전에 동기 실행 → 렌더링을 잠깐 막을 수 있음
  • 남용하면 성능 저하
  • 서버 컴포넌트/SSR에서는 경고 (브라우저에만 layout 개념이 있음)

깜빡임 예시

// useEffect — 잠깐 잘못된 위치가 보였다가 이동할 수 있음
useEffect(() => {
  setTop(ref.current.offsetTop);
}, []);

// useLayoutEffect — paint 전에 위치 확정
useLayoutEffect(() => {
  setTop(ref.current.offsetTop);
}, []);

툴팁·팝오버·측정 기반 UI에서 차이가 납니다.


언제 뭘 쓸까

DOM 측정/수정 때문에 화면이 깜빡이나?
  → Yes: useLayoutEffect
  → No:  useEffect (기본)

원칙: 특별한 이유 없으면 useEffect만 쓰세요. useLayoutEffect는 “paint 전에 꼭 해야 한다”는 게 확실할 때만.


자주 헷갈리는 점

  • 데이터 fetch → useEffect (layout 아님)
  • 상태 업데이트 둘 다 가능하지만, layout은 동기라서 연쇄 렌더가 paint 전에 일어남
  • React 18 Strict Mode — 개발 모드에서 둘 다 두 번 돌 수 있음 (의도된 동작)
  • Next.js App Router — 클라이언트 컴포넌트("use client")에서만 사용

요약

useEffect = 그린 뒤에 해도 되는 일

useLayoutEffect = 그리기 전에 DOM/레이아웃을 맞춰야 하는 일

thankqcamping처럼 스크롤·Intersection Observer·모달 위치 잡는 코드에서 측정 후 즉시 스타일을 바꿔 깜빡임을 막을 때만 useLayoutEffect를 검토하시면 됩니다. 🙏