React/최적화/Lesson 18
useTransition / useDeferredValue — 무거운 업데이트를 백그라운드로
30분·theory
이 챕터
1/2
TypeScript
useTransition / useDeferredValue — 무거운 업데이트를 백그라운드로
💡 왜 배워야 할까요? — 인풋이 끊기는 이유
🎯
검색창에 빠르게 타이핑하면 인풋이 끊기는 경험 — 입력 값 변경이 무거운 필터링·렌더링과 같은 우선순위로 처리되어서.
💼
useTransition 은 '이 state 업데이트는 급하지 않다 — 인풋이 더 중요하다' 를 React 에게 알려줍니다.
⚡
React 는 인풋 업데이트를 먼저 보여주고, 무거운 업데이트는 백그라운드로 양보 → 인풋이 매끄러워짐.
🔗
useDeferredValue 는 비슷한 효과를 '값' 단위로. 무거운 자식 컴포넌트에 deferred 된 값만 흘려보내는 패턴.
📈
예전엔 디바운스·throttle 로 처리하던 UX 문제를 React 가 시간 슬라이싱으로 해결.
🏢 실무에서는
검색 자동완성, 큰 리스트 필터링, 차트 데이터 변경, 무거운 마크다운 프리뷰 — 모두 useTransition 의 영역. 사용자는 '인풋이 부드럽다' 만 느끼고 무거운 부분은 알아서 백그라운드에서 그려짐.
useTransition · useDeferredValue · startTransition
1. useTransition — '이 setState 는 양보 가능' 표시
- ▸
startTransition(fn)안의 setState 는 양보 가능으로 표시. - ▸React 는 더 급한 업데이트(인풋·클릭)가 있으면 그것을 먼저 처리.
- ▸
isPending으로 양보된 업데이트가 진행 중인지 확인 → 스피너 표시.
2. useDeferredValue — 값을 '뒤로 미룬 복사본' 으로
- ▸
query는 즉시 업데이트(인풋 매끄러움). - ▸
deferredQuery는 React 가 한가할 때 따라옴. - ▸
HeavyResults가 deferredQuery 로 무거운 작업을 해도 인풋은 영향 받지 않음.
3. 언제 무엇을?
4. startTransition — hook 없이도 호출 가능
5. 주의
- ▸작업이 진짜 무거우면 (1초 이상) useTransition 으로도 부족. Web Worker 등이 필요.
- ▸fetch 자체는 양보 불가 — fetch 응답을 처리하는 setState 만 양보 가능.
- ▸'스케줄링 힌트' 일 뿐 — React 가 정말 양보할 수 있을 때만 양보.
💡 💡 useTransition / useDeferredValue 실전 5
1. 인풋은 즉시, 결과는 양보 — 가장 흔한 패턴
2. isPending 으로 진행 상태 표시
3. fetch 응답 처리는 양보 가능, fetch 자체는 양보 불가
4. useDeferredValue = '받은 값' 단위, useTransition = '내가 호출' 단위
부모에게서 받은 props 가 자주 바뀌고 그걸 받은 자식이 무겁다 → useDeferredValue.
5. 디바운스의 부분 대체이지 완벽 대체는 아님
useTransition 은 시간 슬라이싱, 디바운스는 호출 자체를 줄임. 보통 둘 중 하나, 상황 따라 선택.
⚡ 직접 실행해보기 — startTransition 흐름
긴급 vs 양보 가능한 업데이트의 우선순위를 시뮬레이션합니다.
✏️ JS 코드
📟 콘솔 출력
▶ 실행 버튼을 눌러보세요
⚠️ 브라우저 샌드박스에서 실행 — console.log()만 지원, alert/fetch 불가
확인 퀴즈
검색창 입력 중 자동완성 렌더링이 무거워서 인풋이 끊깁니다. 가장 적절한 도구는?
먼저 읽으면 좋은 개념: Zustand — 요즘 1티어 전역 상태