Suggest an editImprove this articleRefine the answer for “What does useTransition() do?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)`useTransition()` lets you **mark a state update as "transitional"** (non-urgent) so that React **does not block the interface** during heavy re-renders. **Key point:** useTransition tells React "this update can happen later, do not stall the UI".Shown above the full answer for quick recall.Answer (EN)Image## What `useTransition()` does `useTransition()` lets you **mark a state update as "transitional"** (non-urgent) so that React **does not block the interface** during heavy re-renders. > In simpler terms: > `useTransition()` tells React: > **"This update can happen later, do not stall the UI."** --- ## Syntax ```javascript const [isPending, startTransition] = useTransition(); ``` - `startTransition(callback)` - wraps code that triggers an *unhurried* update. - `isPending` - a boolean value (`true` during the transition), shows that React is still "rendering" the deferred state. --- ## Example Imagine you have a large amount of data, and the user types text to filter a list. ### Without `useTransition` ```javascript function Search() { const [query, setQuery] = useState(""); const [results, setResults] = useState([]); const handleChange = (e) => { const value = e.target.value; setQuery(value); // a heavy operation setResults(filterBigData(value)); }; return ( <> <input value={query} onChange={handleChange} /> <List data={results} /> </> ); } ``` The problem: - Every keystroke (`setQuery`) immediately triggers the heavy `filterBigData`. - The UI "freezes" (lags) on every keypress. --- ### With `useTransition` ```javascript import { useState, useTransition } from "react"; function Search() { const [query, setQuery] = useState(""); const [results, setResults] = useState([]); const [isPending, startTransition] = useTransition(); const handleChange = (e) => { const value = e.target.value; setQuery(value); startTransition(() => { // this update is not urgent setResults(filterBigData(value)); }); }; return ( <> <input value={query} onChange={handleChange} /> {isPending && <p>Loading...</p>} <List data={results} /> </> ); } ``` Now: - React **first** instantly updates `query` (an urgent update), - and **then**, when there is time, does `setResults` (unhurried), - while the interface stays responsive (you can keep typing). --- ## What React does internally React 18 has a **Concurrent Renderer**, which can *pause* and *interrupt* a render if something more important comes up, for example, the user is typing. `useTransition` simply marks a piece of work as: > "It is fine if this waits." React then: - pauses the heavy render, - shows the old UI, - continues once the main thread frees up. --- ## Returned values | Variable | Type | Description | | --- | --- | --- | | `isPending` | boolean | `true` while the transition is not finished | | `startTransition(callback)` | function | wraps "unhurried" updates | --- ## When to use `useTransition()` | When | Why | | --- | --- | | Filtering, search, sorting in large lists | So typing does not freeze | | Pagination or navigation between large components | So the transition does not freeze the UI | | Dynamic data loading | So user actions are not blocked | | When you need to visually separate "instant" and "deferred" updates | For example, `isPending` = true → show "Loading…" | --- ## When **not** to use it | Situation | Why | | --- | --- | | Simple updates (`setState` in a button) | `useTransition` would complicate the code with no benefit | | API requests or asynchronous data | Use `useEffect` or `useQuery` | | You have no problem with UI "lag" | React already optimizes simple cases well enough | --- ## Comparison with regular `setState` | Update | What React does | | --- | --- | | `setState()` | Runs immediately (high priority) | | `startTransition(() => setState())` | Marked as "low priority", React may defer it | --- ## Example: switching pages ```javascript function Tabs({ tabs }) { const [active, setActive] = useState(0); const [isPending, startTransition] = useTransition(); return ( <> {tabs.map((tab, i) => ( <button key={i} onClick={() => startTransition(() => setActive(i))} disabled={isPending} > {tab.title} </button> ))} <div> {isPending ? <p>Loading tab...</p> : tabs[active].content} </div> </> ); } ``` Switching is instant, even if the tab content is large - React "loads" it calmly, without blocking the interface. --- ## Summary | Question | Answer | | --- | --- | | What does `useTransition()` do | Lets you run low-priority (deferred) state updates | | When React runs them | After urgent ones (typing, clicks, hover, etc.) | | What it returns | `[isPending, startTransition]` | | When to use it | For heavy computations, filtering, transitions between large components | | When not to | For simple updates or asynchronous API requests |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.