useDeferredValue lets you defer updating a slow part of the screen so high-priority user interactions—like typing into a search box—stay instant. When a user types rapidly, React updates the input field immediately with the latest text while allowing expensive list filtering or chart redraws to catch up in the background.
Pass the fast-changing state (query) into useDeferredValue(query). During an urgent keystroke render, deferredQuery holds the previous value, then React schedules a background render with the newest query that can be interrupted if the user keeps typing.
import { memo, useDeferredValue, useState } from 'react';
const SlowResultList = memo(function SlowResultList({ filterText }) {
const matches = [];
for (let i = 0; i < 4000; i += 1) {
const label = `Record #${i}`;
if (label.toLowerCase().includes(filterText.toLowerCase())) {
matches.push(<li key={i}>{label}</li>);
}
}
return <ul>{matches.slice(0, 50)}</ul>;
});
export function DirectoryFilter() {
const [query, setQuery] = useState('');
const deferredQuery = useDeferredValue(query);
const isStale = query !== deferredQuery;
return (
<section>
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Filter 4,000 records..."
/>
<div style={{ opacity: isStale ? 0.6 : 1 }}>
<SlowResultList filterText={deferredQuery} />
</div>
</section>
);
}
useDeferredValue vs DebouncingUnlike setTimeout debouncing, useDeferredValue has no fixed delay: on fast laptops the list updates nearly instantly, while on slower phones React yields between keystrokes automatically without freezing the keyboard.
useDeferredValue MistakesReact.memo on the Heavy Child: Without wrapping SlowResultList in memo, the parent re-renders SlowResultList synchronously on every keystroke even before deferredQuery updates.useDeferredValue({ query }) creates a new object on every render and triggers unnecessary background renders. Pass primitive values or memoized objects instead.Yes. React 19 accepts an optional second parameter useDeferredValue(value, initialValue) for initial mount rendering before showing the deferred value.
useDeferredValue instead of useTransition?Use useDeferredValue when you receive a changing prop or value from outside and cannot wrap its setState call directly; use useTransition when you control the state setter.
useDeferredValue stop network calls?No. To avoid sending an HTTP request on every keystroke, combine debouncing or React Query cancellation with useDeferredValue.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
You've completed this section! Take a quick 5-question quiz to check your understanding.