useDeferredValue lets React defer updating part of the UI when a value changes, keeping urgent interactions responsive while expensive content catches up.
const [search, setSearch] = useState("");const deferredSearch = useDeferredValue(search);
search for the controlled input so typing responds immediately.deferredSearch for expensive rendering, such as filtering a large list.import { memo, useDeferredValue, useState } from "react";const PokemonList = memo(function PokemonList({pokemons,search,}: {pokemons: { id: number; name: string }[];search: string;}) {const filtered = pokemons.filter(pokemon =>pokemon.name.toLowerCase().includes(search.toLowerCase()));return (<ul>{filtered.map(pokemon => (<li key={pokemon.id}>{pokemon.name}</li>))}</ul>);});function PokemonSearch({ pokemons }) {const [search, setSearch] = useState("");const deferredSearch = useDeferredValue(search);const isPending = search !== deferredSearch;return (<><inputvalue={search}onChange={event => setSearch(event.target.value)}placeholder="Search Pokémon..."/>{isPending && <span>Updating results...</span>}<div style={{ opacity: isPending ? 0.6 : 1 }}><PokemonListpokemons={pokemons}search={deferredSearch}/></div></>);}
Here, memo allows PokemonList to skip rendering during urgent parent updates when its props remain unchanged. The deferred search value then updates separately, allowing React to prioritize typing over expensive filtering.
useDeferredValue can also help coordinate UI that suspends while loading data, but it does not itself initiate, debounce, or cache requests.
For Suspense-based fetching, use a data source that provides stable, cached resources or a Suspense-compatible framework. Avoid creating a fresh Promise directly during every render.