Concurrent React APIs allow you to keep the UI responsive during heavy rendering or data fetching.
Suspense
Declaratively show a fallback UI while children are loading (e.g., waiting for a promise via use or a lazy component).
use
Reads the value of a context or a promise. Unlike useContext, use can be called inside conditions and loops and integrates with Suspense for promises.
useTransition
Marks a state update as non-urgent. This prevents heavy renders from blocking urgent interactions like typing or scrolling.
- Async Transitions (React 19): The function passed to
startTransition can be async. isPending will remain true until the entire async operation completes.
useDeferredValue
Defers re-rendering a part of the UI that is expensive to compute. The deferred value lags behind the actual value, allowing urgent updates to flush first.
- initialValue (React 19): Accepts a second argument to provide a value to use during the initial render before the deferred value catches up.
// Suspense + use
const UserProfile = ({ userPromise }: { userPromise: Promise<User> }) => {
const user = use(userPromise);
return <p>{user.name}</p>;
};
// useTransition
const [isPending, startTransition] = useTransition();
const selectTab = (next: string) => {
startTransition(() => {
setTab(next);
});
};
// useDeferredValue
const deferredQuery = useDeferredValue(query, "");