useTransition
React chapter 16 · React 18 · concurrent rendering · source: react.dev/reference/react/useTransition
The problem
Every keystroke redraws a slow list in the same update. The input has to wait for the list, so typing feels sticky.
The pattern that fixes it
Keep the input as urgent state. Wrap only the list state in startTransition. React paints the input first and renders the list when it can, and isPending tells you the list is catching up.
In plain words
Some updates must feel instant (the letter you typed) and some can take a moment (a big list that reacts to it). useTransition lets you label the second kind as "not urgent", so React does the urgent one first.
A waiter takes your order straight away (urgent), then the kitchen cooks it in the background (not urgent). He does not stand at the stove while you wait with the menu in your hand.
Terms
- urgent update
- Something the person expects to see right now, like text appearing in an input.
- transition
- An update you mark as non-urgent. React may pause or throw away its work if something urgent arrives.
- isPending
- A boolean from useTransition that is true while the transition has not finished yet.
- commit
- The moment React applies a finished render to the screen.
Going deeper
How does it work?
Normally a render runs to the end without stopping. Work inside startTransition is rendered in small slices. If you type again mid-way, React drops the half-done list render, paints the new input value first, then starts the list again with the newest text. That is why the list may commit fewer times than you typed letters.
Pitfalls: when it does nothing
It cannot make a slow render faster, it only reorders the work. If the input state itself goes inside the transition, typing lags again. If the list is not skipped while the input re-renders (no memo), the slow work still runs in the urgent update. Updates inside a transition must be synchronous state updates, not code after an await.
When not to use it, and alternatives
First make the render cheaper: fewer rows, virtualization (draw only visible rows), or move the filter into a worker. If you do not own the setter and only receive the value, use useDeferredValue (next chapter). The React Compiler can skip some wasted work, but it does not label updates as urgent or not.
Keep learning
- Previous: useEffectEvent
- Next: useDeferredValue
- Related: memo
- Related: useMemo
- Related: useCallback
- Related: Custom hooks
- Related: useEffectEvent
- Related: useDeferredValue
More courses
- Jobs, linked to lessons — Browse jobs where every requirement links to the chapter that teaches it. See how ready you are, how long the gap takes to close, and which listings look stale.
- Match a job post to courses — Paste a job post. Each skill is matched to a track here and put in learning order, foundations first.
- Database in depth — How a query becomes work. Indexes, isolation, locks, and the plans that explain why a page is slow — not an ORM tour.
- System Design — Eight interview case studies, from a flash sale and Tatkal to a live final and a chat model, plus JWT in separate chapters.
- Microservices — Microservice patterns one diagram at a time: how to split a monolith, how services talk, and how data stays consistent without distributed transactions.
- Kafka — A beginner-to-senior path through event logs, reliable delivery, production operations, and disaster recovery.
- Frontend system design — How a UI is sliced when it is a product, not a page: ownership of state, cache, routes, and what happens when the network lies.
- CSS in depth — See the box, then the page. Visual chapters from the box model through Flexbox surprises, Grid, selectors, and units, then backgrounds, shapes, and visual effects, each with a playground.
- Accessibility — HTML labs first, then a full pass of WAI-ARIA 1.3: naming, every state, widget and structure roles, live regions, ariaNotify, and relationships.
- Docker — What an image is, why layers cache, and how containers find each other on a network.
- Redis — Fifteen Redis patterns, one picture each: cache, session, lock, counter, rate limiter, queue, and when Redis is the wrong tool.