React/Optimization/Lesson 18
useTransition / useDeferredValue — Push Heavy Updates to the Background
30 min·theory
This chapter
1/2
TypeScript
useTransition / useDeferredValue — Push Heavy Updates to the Background
💡 Why Learn This? — Why Input Stutters
🎯
When you type quickly in a search box, the input feels sluggish — because the value change is processed at the same priority as heavy filtering and rendering.
💼
useTransition tells React: 'This state update is not urgent — the input matters more.'
⚡
React shows the input update first and yields the heavy update to the background → the input becomes smooth.
🔗
useDeferredValue achieves a similar effect at the 'value' level — a pattern where only the deferred value is passed down to a heavy child component.
📈
UX problems that used to be handled with debounce or throttle are now solved by React through time slicing.
🏢 실무에서는
Search autocomplete, large list filtering, chart data changes, heavy markdown previews — all fall within the domain of useTransition. Users only notice that 'the input is smooth,' while the heavy parts are rendered in the background automatically.
useTransition · useDeferredValue · startTransition
1. useTransition — Mark a setState as 'yieldable'
- ▸setState calls inside
startTransition(fn)are marked as yieldable. - ▸React processes more urgent updates (input, clicks) first if they arrive.
- ▸Use
isPendingto check whether a yielded update is in progress — show a spinner.
2. useDeferredValue — A 'deferred copy' of a value
- ▸
queryupdates immediately (smooth input). - ▸
deferredQueryfollows when React has spare capacity. - ▸Even if
HeavyResultsdoes heavy work with deferredQuery, input remains unaffected.
3. When to use which?
4. startTransition — Callable without the hook
5. Caveats
- ▸If the work is truly heavy (over 1 second), useTransition alone is not enough — a Web Worker may be required.
- ▸fetch itself cannot yield — only the setState that processes the fetch response can yield.
- ▸These are merely 'scheduling hints' — React only yields when it actually can.
💡 💡 useTransition / useDeferredValue — 5 Practical Tips
1. Input is immediate, results yield — the most common pattern
2. Show progress with isPending
3. Processing a fetch response can yield, but the fetch itself cannot
4. useDeferredValue = per 'received value' unit, useTransition = per 'your own call' unit
If props received from a parent change frequently and the child consuming them is heavy, use useDeferredValue.
5. A partial substitute for debounce, not a complete one
useTransition uses time-slicing; debounce reduces the number of calls. Typically choose one or the other depending on the situation.
⚡ Try It Yourself — startTransition Flow
Simulates the priority between urgent and yieldable updates.
✏️ JS 코드
📟 Console output
▶ Press the Run button
⚠️ Runs in a browser sandbox — only console.log() is supported; alert/fetch are not.
Check Quiz
While typing in a search box, autocomplete rendering is so heavy that input stutters. What is the most appropriate tool to use?
Read this first: Zustand — Top-tier Global State Today
Up next: React.memo / useMemo / useCallback