# Understanding useTransition()
Normally, all state updates in React are urgent. If you click a button or type in an input and it triggers a slow render, the browser freezes until the render is complete. useTransition fixes this by making updates "non-urgent" (interruptible).
Background
By default, every state update in React is treated as urgent.
This means that whenever you call a state setter, React immediately schedules a re-render. For small updates this is usually fast, but when an update causes an expensive render—such as filtering thousands of records or rendering a large table—the interface can begin to feel sluggish.
useTransition() allows you to tell React that certain updates are non-urgent. React can then prioritize user interactions such as typing or clicking before finishing those updates.
Syntax
import { useTransition } from "react";
const [isPending, startTransition] = useTransition();
useTransition() returns:
isPending—truewhile React is rendering a transition.startTransition()— marks the enclosed state updates as low priority.
How It Works
When React encounters:
startTransition(() => {
setFilteredProducts(products);
});
it schedules that state update with a lower priority than user interactions.
If a higher-priority update arrives before the transition finishes, React pauses the transition, handles the urgent update, and then continues with the latest transition.
Example
const [query, setQuery] = useState("");
const [filtered, setFiltered] = useState(products);
const [isPending, startTransition] = useTransition();
function handleChange(value: string) {
setQuery(value);
startTransition(() => {
setFiltered(filterProducts(value));
});
}
In this example:
- Updating the input value is urgent.
- Updating the filtered list is non-urgent.
- Typing remains responsive even if filtering thousands of products takes time.
isPending
Use isPending to indicate that React is still processing the transition.
<button disabled={isPending}>
{isPending ? "Filtering..." : "Filter"}
</button>
Important Notes
useTransition()does not make your code faster.- It changes the priority of state updates.
- Only state updates inside
startTransition()become transitions. - Avoid wrapping controlled input state inside
startTransition(), otherwise typing may become delayed.
When Should You Use It?
useTransition() is useful when a state update causes an expensive render, for example:
- Filtering large datasets, Rendering large tables, Updating charts. Avoid using it for small or inexpensive updates.
Understanding Suspense
Suspense is a built-in React component that allows you to display a fallback UI while part of your component tree is not yet ready to render.
Instead of blocking the entire page, React temporarily renders the fallback and replaces it with the real content once the suspended component is ready.
import { Suspense } from "react";
<Suspense fallback={<SkeletonLoader />}>
<MySlowComponent />
</Suspense>
Why Suspense Exists
Imagine a page with two sections:
- Header (loads instantly)
- Product list (takes 3 seconds)
Without Suspense, React may have to wait before showing the entire page. With Suspense, React can display the parts that are already available while the slower section continues loading.
What Can Suspend?
Suspense does not fetch data by itself. Instead, it waits for components that suspend during rendering.
Common examples include:
- Components loaded with
React.lazy() - Server Components waiting for database queries
- Frameworks like Next.js that integrate data fetching with Suspense
- Libraries that support Suspense by suspending during rendering
Rendering Models
Understanding Suspense becomes easier when comparing different rendering strategies.
1. Client-Side Rendering (SPA)
In a traditional Single Page Application (SPA), the server sends an almost empty HTML page.
<body>
<div id="root"></div>
<script src="/main.js"></script>
</body>
The browser must:
- Download JavaScript.
- Execute JavaScript.
- Render the page.
2. Traditional Server-Side Rendering (SSR)
With traditional SSR, the server waits until all data is available before sending the page.
<body>
<header>My Site</header>
<main>
<ul>
<li>Post 1</li>
<li>Post 2</li>
</ul>
</main>
</body>
The page is complete, but the user waits for the slowest operation before seeing anything.
3. Streaming SSR with Suspense
Streaming SSR allows React to send completed parts of the page immediately.
<body>
<header>My Site</header>
<main>
<div class="spinner">
Loading posts...
</div>
The server keeps the connection open.
Once the slow component finishes rendering, React streams another HTML chunk that replaces the fallback.
Notice that only the suspended subtree waits.
The rest of the page can continue rendering normally.
Benefits
- Improves perceived performance.
- Prevents the entire page from waiting on slow components.
- Enables streaming Server-Side Rendering.
- Works naturally with
React.lazy(). - Allows independent sections of a page to load at different times.
Comments (0)
No comments yet. Be the first to share your thoughts.