What does startTransition() do?
What startTransition() does
startTransition() tells React:
"This update is not urgent. You can wait until the user finishes interacting and do it later, so you do not slow down the interface."
Syntax
import { startTransition } from 'react';
startTransition(() => {
setState(newValue);
});React will perform this update with a low priority. If something important happens at the same time (for example, the user is typing or clicking), React will first update the urgent things, and only then "finish" the transition.
Why this is needed
Without startTransition, all updates are treated as urgent.
This means React immediately interrupts everything to render the new UI.
For example, the user is typing into a search box while you filter a huge list.
function Search() {
const [query, setQuery] = useState('');
const [filtered, setFiltered] = useState(data);
const handleChange = e => {
const value = e.target.value;
setQuery(value);
setFiltered(filterItems(data, value)); // heavy operation
};
return (
<>
<input value={query} onChange={handleChange} />
<List items={filtered} />
</>
);
}On every character typed, React:
- updates
query, - filters the entire list,
- re-renders a ton of elements.
The interface starts to "lag".
With startTransition - smooth magic
import { startTransition } from 'react';
function Search() {
const [query, setQuery] = useState('');
const [filtered, setFiltered] = useState(data);
const handleChange = e => {
const value = e.target.value;
setQuery(value); // urgent update - the input text changes instantly
startTransition(() => {
setFiltered(filterItems(data, value)); // low-priority update
});
};
return (
<>
<input value={query} onChange={handleChange} />
<List items={filtered} />
</>
);
}Now React separates the updates:
setQuery-> high priority (the UI must respond instantly);setFiltered-> low priority (it can wait).
The result:
- the input field works without lag;
- the list is filtered a bit later, once React is free.
What React does internally
- React puts the transition task into a low-priority queue;
- It keeps handling all urgent updates (input, clicks, hover, and so on);
- When there is a "window of time", it renders the low-priority update;
- If the user types another character, React can interrupt the old render and start a new one.
This is what "concurrent rendering" means.
An example with a "transition in progress" indicator
React provides the useTransition() hook to track
whether a transition is currently in progress.
import { useState, useTransition } from 'react';
function Search() {
const [query, setQuery] = useState('');
const [filtered, setFiltered] = useState(data);
const [isPending, startTransition] = useTransition();
const handleChange = e => {
const value = e.target.value;
setQuery(value);
startTransition(() => {
setFiltered(filterItems(data, value));
});
};
return (
<>
<input value={query} onChange={handleChange} />
{isPending && <p>Updating the list...</p>}
<List items={filtered} />
</>
);
}Now isPending is true while React performs the transition.
You can show a spinner, a loading indicator, and so on.
The key idea
React 18 can prioritize updates:
| Priority | Example | How it runs |
|---|---|---|
| Urgent | Input, clicks, animations | Immediately |
| Non-urgent (Transition) | Filtering, rendering lists, loading | When there is time |
When to use startTransition
Good for:
- filtering or sorting large lists;
- switching tabs that load data;
- updating the UI when a filter, language, theme, or category changes;
- any operation where responsiveness matters more than an instant render.
Not needed for:
- simple
setState; - instant effects (modals, clicks);
- cases with no heavy render.
Why this matters
| Benefit | What it gives |
|---|---|
| The UI stays responsive | The user can click and type while the transition runs |
| Priority separation | React decides on its own what is more important |
| Interruptible renders | React can cancel an old transition |
| Fewer lags | Heavy updates do not block the interface |
Summary
| What it does | How it works |
|---|---|
startTransition() | Marks an update as "not urgent" |
| React 18 concurrent mode | Lets React interrupt and prioritize renders |
| High priority | For instant UI (input, clicks) |
| Low priority (transition) | For heavy operations |
useTransition() | A hook to show a "transition in progress" state |
In simple words:
startTransition()tells React: "This is not critical - do it when you have time, but do not block the user's interface."
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.