useEffect vs useLayoutEffect

Hushed_Mind·2025년 4월 24일

React

목록 보기
6/7
post-thumbnail

React에서 렌더링 후 어떤 작업을 수행할 때 우리는 흔히 useEffect를 사용한다.
하지만 동일한 문법, 다른 타이밍으로 작동하는 useLayoutEffect도 존재한다.

그저 "하나는 비동기, 하나는 동기"라고 외워두기보다는,
이 둘이 왜 분리되었는지,
리액트의 렌더링 구조상 어떤 목적을 위한 것인지
그리고 우리가 언제 어떤 것을 선택해야 하는지를 구조적으로 이해해보자.


왜 둘로 나뉘었을까?

리액트는 기본적으로 렌더링 결과를 화면에 출력하는 일을 브라우저에게 위임한다.
즉, 컴포넌트 함수가 실행되면 가상 DOM이 만들어지고,
브라우저는 이걸 실제 DOM으로 패치하고, 화면을 그린다.

그런데 여기서 문제가 생긴다.

"렌더링 후 어떤 작업을 해야 할 때, 정확히 언제 해야 할까?"

예를 들어:

  • 화면이 그려진 후 데이터를 가져오고 싶다 → 늦게 실행되어도 무방
  • 화면이 그려지기 전에 요소 크기를 계산해 위치를 잡아야 한다 → 화면이 바뀌기 전이어야 함

이처럼 렌더링 이후의 타이밍은 두 종류로 나뉘는 작업의 본질을 반영한다.

그래서 React는 이 후처리 작업을 위해 두 개의 훅을 제공한다:

  1. useEffect렌더링 후, 브라우저 페인트가 끝난 뒤 실행 (비동기)
  2. useLayoutEffect렌더링 후, DOM이 완성되었지만 브라우저가 아직 그리기 전에 실행 (동기)

구조적으로 언제 실행되나?

단계설명관련 훅
1. 컴포넌트 함수 실행리렌더링 준비-
2. 가상 DOM 생성JSX → ReactElement → 가상 DOM-
3. 실제 DOM 업데이트브라우저에게 실제 DOM 변경 명령-
4. useLayoutEffect 실행DOM 완성됨, 브라우저가 그리기 직전
5. 브라우저가 화면 페인팅사용자에게 화면 보임-
6. useEffect 실행렌더링이 끝난 후 (비동기)

즉,

  • useLayoutEffectDOM을 변경할 수 있는 마지막 기회
  • useEffect화면이 사용자에게 보인 후 처리하면 되는 일들

실무 기준: 어떤 작업을 어디에?

useEffect에 적합한 작업

  • 비동기 API 호출
  • 이벤트 리스너 등록/해제
  • 로컬 스토리지 작업
  • 외부 라이브러리 초기화 (시각적 영향 없는 경우)
useEffect(() => {
  fetchData().then(setData);
}, []);

useLayoutEffect에 적합한 작업

  • DOM의 크기, 위치 측정
  • 스크롤 조작
  • CSS 클래스 조작 (렌더링 전 상태 반영)
  • 레이아웃 플리커 방지
useLayoutEffect(() => {
	const height = ref.current.offsetHeight;
    setHeight(height); // setState -> 즉시 DOM 반영된다.
},[]);

왜 useLayoutEffect는 위험할 수 있나?

useLayoutEffect동기적으로 실행된다.
즉, 이 안에서 오래 걸리는 작업을 하면 렌더링이 차단되고,
UI가 멈춘 듯한 느낌을 줄 수 있다.

useLayoutEffect(() => {
	whie (true) {} // 브라우저 멈춤
}, []);

그래서 일반적으로 항상 useEffect를 먼저 쓰고,
"시각적으로 깜빡임이나 DOM 위치 오류"가 있을 때만
useLayoutEffect로 바꾸는 방식이 추천된다.


예시: 깜빡임이 생기는 경우

// 깜빡임 있는 경우
useEffect(() => {
	const h = ref.current.offsetHeight;
  	setTop(h);
},[]);
  • useEffect는 렌더링 후에 실행
  • 이미 한번 그린 화면에서 위치를 바꾸게 됨 -> 깜빡임
// 깜빡임 없는 경우
useLayoutEffect(() => {
	const h = ref.current.offsetHeight;
  	setTop(h);
},[]);
  • useLayoutEffect는 DOM이 완성되었지만 아직 화면에 그려지기 전
  • 위치 보정 후 브라우저가 그리므로 자연스러움

결론

useEffect와 useLayoutEffect의 차이는
단순히 "빠르냐 느리냐"가 아니라,
렌더링 이후 작업을 '어느 타이밍에서 통제할 것이냐'의 문제다.

렌더링 사이클을 정확히 이해하고,
우리가 통제하고자 하는 대상(DOM 구조인지, 시각 결과인지)을 기준으로
적절한 훅을 선택하는 것이 진짜 실력이다.

profile
개발 공부 블로그

0개의 댓글