Using startTransition
In this tutorial, you will learn how to use startTransition to keep your UI responsive during heavy updates.
startTransition lets React prioritize user interactions over expensive renders without you manually managing performance hacks.
What We Will Learn
- What
startTransitionis and why it exists - The difference between urgent and non urgent updates
- How React schedules work during transitions
- Real world examples where
startTransitionmatters - Common mistakes and best practices
By the end, you will know exactly when and why to use transitions.
The Problem startTransition Solves
Sometimes an update is:
- Computationally expensive
- Causes many components to re-render
- Blocks typing, clicking, or scrolling
Example problems users notice:
- Typing feels laggy
- Buttons freeze briefly
- Search results lock the UI
The issue is not correctness. The issue is priority.
Urgent vs Non Urgent Updates
React 19 treats updates in two categories:
Urgent Updates
- Typing in an input
- Clicking buttons
- Hover interactions
- Focus changes
These must feel instant.
Non Urgent Updates
- Filtering large lists
- Sorting data
- Rendering charts
- Navigating between views
These can wait a little without harming UX.
What startTransition Does
startTransition tells React:
This update is important, but do it when the browser is free.
React then:
- Keeps the UI responsive
- Interrupts rendering if the user interacts
- Finishes the transition when possible
Nothing blocks the main thread unnecessarily.
Basic Example Without startTransition
// components/search.tsx
"use client"
import { useState } from "react"
export function Search({ items }: { items: string[] }) {
const [query, setQuery] = useState("")
const results = items.filter(item =>
item.toLowerCase().includes(query.toLowerCase())
)
return (
<>
<input
value={query}
onChange={e => setQuery(e.target.value)}
/>
<ul>
{results.map(item => (
<li key={item}>{item}</li>
))}
</ul>
</>
)
}Typing updates query and filters immediately.
If items is large, typing becomes sluggish.
Adding startTransition
// components/search.tsx
"use client"
import { useState, startTransition } from "react"
export function Search({ items }: { items: string[] }) {
const [query, setQuery] = useState("")
const [filtered, setFiltered] = useState(items)
function onChange(value: string) {
setQuery(value)
startTransition(() => {
setFiltered(
items.filter(item =>
item.toLowerCase().includes(value.toLowerCase())
)
)
})
}
return (
<>
<input
value={query}
onChange={e => onChange(e.target.value)}
/>
<ul>
{filtered.map(item => (
<li key={item}>{item}</li>
))}
</ul>
</>
)
}Now:
- Typing stays instant
- Filtering happens in the background
- React pauses work if the user keeps typing
What Changed Conceptually
Before:
- One update
- Everything blocks until done
After:
- Urgent update first
- Heavy work scheduled later
- UI remains interactive
You did not optimize the algorithm. You optimized priority.
Transitions Are Not Async
This is important.
startTransition does not:
- Make code async
- Delay execution with timers
- Run on another thread
It only tells React how to schedule the update.
Showing Pending State with useTransition
Sometimes you want to show feedback.
import { useTransition } from "react"
const [isPending, startTransition] = useTransition()Example:
<button disabled={isPending}>
{isPending ? "Updating..." : "Update"}
</button>This helps users understand that work is happening.
Common Use Cases
Use startTransition for:
- Search filtering
- Sorting tables
- Pagination
- Switching tabs with heavy content
- Rendering large lists
Avoid it for:
- Controlled inputs
- Form validation
- Immediate UI feedback
Common Mistakes
Wrapping Everything in a Transition
Do not do this:
startTransition(() => {
setInput(value)
})Typing must always be urgent.
Using Transitions as a Performance Fix
If your code is slow because of bad algorithms, fix that first.
startTransition is about user experience, not brute force optimization.
How This Fits with the React Compiler
The React Compiler optimizes re-renders.
startTransition optimizes when rendering happens.
They solve different problems and work best together.
Mental Model
Think of startTransition like a priority lane:
- User interactions go in the fast lane
- Heavy rendering goes in the slow lane
- React switches lanes automatically
This keeps the app feeling smooth.
Conclusion
startTransition is a powerful but focused tool in React 19.
It helps you:
- Keep UIs responsive
- Prioritize user interactions
- Handle heavy updates gracefully