Non-blocking navigation
Keep tab, route, or panel navigation responsive while rendering the newly selected view.
React 19+ · Hook
useTransition lets a component mark non-urgent state updates as background Transitions. It returns a pending flag and a function for starting them.
Call this Hook at component level to obtain a pending indicator and a function for marking state updates as Transitions. The callback runs immediately; synchronous updates inside it receive transition priority, while async work in React 19 can keep the pending state active and requires wrapping post-await state updates in another transition.
const [isPending, startTransition] = useTransition();An array containing [isPending, startTransition]. isPending is a boolean indicating whether a Transition is pending; startTransition is a function that marks updates in its callback as Transitions.
import { useState, useTransition } from 'react';
export default function Tabs() {
const [tab, setTab] = useState('about');
const [isPending, startTransition] = useTransition();
function selectTab(nextTab: string) {
startTransition(() => setTab(nextTab));
}
return (
<div>
<button onClick={() => selectTab('about')}>About</button>
<button onClick={() => selectTab('posts')}>Posts</button>
{isPending && <p>Loading…</p>}
<p>Selected: {tab}</p>
</div>
);
}Marks tab navigation as non-urgent and displays feedback while its transition is pending.
Keep tab, route, or panel navigation responsive while rendering the newly selected view.
Show a spinner or disabled state while a Transition is still in progress.
Run React 19 async Actions that coordinate requests and pending UI.
useTransition returns exactly two values: isPending and startTransition. The flag indicates whether a Transition is pending, and the function marks updates performed by its callback as Transitions.
Follow-up: What should code outside a component use? Use the standalone startTransition function, but it does not provide an isPending indicator.
Call useTransition at the top level of a component or custom Hook. It takes no parameters and returns the pending flag plus the transition-starting function.
Follow-up: Why not call it conditionally? Hooks must follow React's top-level calling rules, so conditional calls would break Hook ordering.
In React 19, startTransition can receive an async function. React sets isPending while the async transition is active; state updates after an await must be wrapped in another startTransition.
Follow-up: What happens to urgent interaction updates? They can interrupt non-urgent transition work, keeping interactions responsive.
startTransitionuseDeferredValueuseOptimisticuseActionState