Skip to main content

What does useDeferredValue() do when working with asynchrony?

What useDeferredValue() does

useDeferredValue(value) defers updating a value so React can first render the fast and important parts of the interface, and update the "heavy" or asynchronous parts a bit later.

In other words:

React makes the UI responsive without blocking the rendering of slow components.


A simple explanation

Picture a search field where every keystroke triggers a request to the server:

javascript
<input value={query} onChange={e => setQuery(e.target.value)} /> <SearchResults query={query} />

The problem:

  • the user types fast - query changes with every character;
  • every render triggers filtering or a network request;
  • the UI starts to "lag" (stutters while typing).

1. How useDeferredValue solves this

javascript
import { useState, useDeferredValue, Suspense } from 'react'; import useSWR from 'swr'; const fetcher = (url) => fetch(url).then(r => r.json()); function SearchResults({ query }) { const { data } = useSWR(`/api/search?q=${query}`, fetcher, { suspense: true }); return <ul>{data.results.map(r => <li key={r}>{r}</li>)}</ul>; } export default function Search() { const [query, setQuery] = useState(''); const deferredQuery = useDeferredValue(query); return ( <> <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search..." /> <Suspense fallback={<p>Loading...</p>}> <SearchResults query={deferredQuery} /> </Suspense> </> ); }

What happens:

  1. The user types fast (query updates instantly).
  2. React does not rush to update the heavy component (SearchResults) for every character.
  3. It holds back the update of deferredQuery until it becomes "free".
  4. As soon as the user stops actively typing -> React updates deferredQuery.

As a result:

  • the input field stays responsive;
  • expensive computations and requests do not block the UI.

2. Behavior in practice

EventquerydeferredQueryWhat React does
The user types "React"changes fast: R -> Re -> Rea -> ...lags behindReact renders only the input
The user has stoppedcatches up with queryloads data for "React"

3. Difference from startTransition()

HookWhat it does
useDeferredValue(value)defers using a value (the reactive version)
startTransition(callback)defers running a state update

An example of equivalent behavior:

javascript
// the startTransition variant import { startTransition } from 'react'; function onChange(e) { const value = e.target.value; setImmediateQuery(value); // update fast (the input) startTransition(() => setDeferredQuery(value)); // deferred - search }

useDeferredValue() does the same thing, but declaratively:

javascript
const deferredQuery = useDeferredValue(query);

4. Typical use cases

CaseWhat useDeferredValue does
Searchdefers updating the results list so typing does not lag
Large listsupdates the list's render a bit later so the UI stays responsive
Suspense data loadinglets you show old data while new data is being loaded
Filters / sortingavoids re-rendering the table on every click
Charts and visualizationrenders updates only when React is "free"

5. An example with a heavy visual load

javascript
function HeavyList({ filter }) { const items = Array.from({ length: 5000 }, (_, i) => `Item ${i}`); const filtered = items.filter(i => i.toLowerCase().includes(filter.toLowerCase())); return ( <ul>{filtered.map(i => <li key={i}>{i}</li>)}</ul> ); } export function Search() { const [filter, setFilter] = useState(''); const deferredFilter = useDeferredValue(filter); return ( <> <input value={filter} onChange={e => setFilter(e.target.value)} placeholder="Filter..." /> <HeavyList filter={deferredFilter} /> </> ); }

With fast typing:

  • the input field reacts instantly (rendering is "not blocked");
  • the list updates with a slight delay (a bit later).

6. How it works "under the hood"

useDeferredValue:

  • returns a "lagged copy" of the value;
  • marks updates that depend on it as low priority;
  • React performs these updates only when the UI is free;
  • if a new value arrives while waiting, the old one is discarded.

This is part of React Concurrent Rendering, a mechanism where React itself decides what to update first and what can wait.


SUMMARY

What it doesWhy it is needed
Defers updating a valueprevents lags with frequent updates
Does not block input and fast updatesthe UI stays responsive
Lets you work smoothly with Suspenseold data stays on screen
Uses low render priorityReact makes a "smart" update plan
Great for search, filters, listsreduces unnecessary requests and renders

In short:

useDeferredValue() is a way to tell React: "Here is a new value, but do not rush to render it - update when there's time."

It makes the interface smooth and responsive, especially with asynchronous data loading or rendering heavy components.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.