Under The Hood
frontend react React 18 / 19

useTransition & Concurrent Lanes: Priority Scheduling & Non-Blocking Updates

Last updated
Prerequisites:
React Fiber Reconciler
State updates with useState
  • react
  • useTransition
  • startTransition
  • concurrent
  • lanes
  • scheduler

Read at your depth

The practical view

`useTransition` is a hook that marks a state update as a non-urgent 'transition'. `const [isPending, startTransition] = useTransition();`. Inside `startTransition(() => { setHeavyState(data); })`, React deprioritizes the update. Urgent updates (like typing in an input or clicking a toggle) can interrupt the transition render, keeping the input responsive. `isPending` tells you if the background transition is currently rendering.

The same idea in other frameworks

react equivalent
`useTransition` / `startTransition` assigning `TransitionLane` priority.

Legacy vs modern

Blocking Input State vs Non-Blocking useTransition

Synchronous state updates for large lists freeze input typing; `useTransition` keeps keystrokes instant while deferring the list update.

before → after
Synchronous Blocking Update
setQuery(val); setList(filter(val)); // ❌ Freezes typing on large lists
Concurrent useTransition
startTransition(() => { setFiltered(filter(val)); }); // ✅ NEW: Non-blocking

Interview gotchas

Context

Tests knowledge of React 18 concurrent primitive specialization.

The mechanical answer

`useTransition` is used when you have direct control over the state-setting function (`startTransition(() => setState(...))`). `useDeferredValue` is used when you receive a value from props or an external hook without direct access to the state setter (`const deferredValue = useDeferredValue(props.value)`). Both use the same underlying Transition Lanes priority mechanism.

Trap

Do not wrap `useDeferredValue` inside `startTransition`. They are complementary approaches for different code locations.

Under The Hood — a multi-depth technical interview hub.

Third-party licenses Press ⌘ K to search.