useTransition is a React hook that marks state updates as non-urgent, allowing React to interrupt the update to handle more urgent interactions (like clicks and typing). It keeps the UI responsive during expensive updates.
How it works:
startTransition(() => setState(...)) instead of calling setState(...) directlyComplete code example:
1import { useState, useTransition } from "react";23const tabs = ["home", "analytics", "reports", "settings"];45function TabContainer() {6 const [isPending, startTransition] = useTransition();7 const [tab, setTab] = useState("home");89 const selectTab = (nextTab: string) => {10 startTransition(() => {11 setTab(nextTab); // Non-urgent, can be interrupted12 });13 };1415 return (16 <div>17 <nav>18 {tabs.map(t => (19 <button20 key={t}21 onClick={() => selectTab(t)}22 disabled={isPending}23 style={{ fontWeight: tab === t ? "bold" : "normal" }}24 >25 {t.charAt(0).toUpperCase() + t.slice(1)}26 </button>27 ))}28 </nav>29 <div style={{ opacity: isPending ? 0.6 : 1 }}>30 {tab === "home" && <HomeTab />}31 {tab === "analytics" && <AnalyticsTab />}32 {tab === "reports" && <ReportsTab />}33 {tab === "settings" && <SettingsTab />}34 </div>35 </div>36 );37}
When to use useTransition:
Key properties:
isPending — true while the transition is in progress (use this to show loading indicators)startTransition — the function that wraps your state updateuseTransition vs useState (without transition): | Scenario | useState | useTransition | |---------|----------|---------------| | User clicks tab | New tab renders immediately, old tab disappears | Old tab stays visible until new tab is ready | | User types while updating | UI freezes until update completes | Typing stays responsive | | Priority | Urgent (blocks UI) | Non-urgent (can be interrupted) |