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를 검토하시면 됩니다. 🙏