React

useDeferredValue: a list that stays responsive

useDeferredValue returns a lagging copy of a value: the field stays immediate and the heavy list updates when there is time.

Key points

  • useDeferredValue waits for no timer: React postpones the render of the deferred value and resumes as soon as it can.
  • The deferred value helps only if the expensive part is memoised, otherwise the parent re-renders it anyway.
  • Comparing the immediate value with the deferred one signals the wait without adding state.

useDeferredValue returns a lagging version of a value: the typed text shows at once, the list that depends on it updates when the browser has time. It is the opposite of a debounce, because it waits for no timer.

The difference from useTransition

useTransition decides when an update you control starts; useDeferredValue starts from the value you already have and needs no rewrite of the setter. When the state lives in a third-party component, the second is the only option.

The runnable case

import { useDeferredValue, useMemo, useState } from "react";
import { ListaRighe } from "./ListaRighe";

export function Ricerca({ righe }) {
  const [testo, setTesto] = useState("");
  const differito = useDeferredValue(testo);
  const attesa = testo !== differito;

  const visibili = useMemo(
    () => righe.filter((r) => r.includes(differito)),
    [righe, differito],
  );

  return (
    
       setTesto(e.target.value)} />
      
    
  );
}

The list reads the deferred value, the input reads the immediate one. Comparing the two switches on the waiting indicator without extra state, and it clears itself when they match.

Why memo matters

The deferred value skips the render of the expensive part only if that part is memoised with memo. Without memo the parent redraws, the child receives new props and the heavy work starts again anyway.

Live records in the catalogue

The search category collects the search fields, with a command menu that filters a list; for a visible wait there is the chat input with a loading state.

The limitation

You have no control over the delay: React decides based on available time, so you cannot promise an answer within three hundred milliseconds. The deferred value does not touch the network, does not cut the number of requests and does nothing for a list without memo.

Where to continue

What changed in the release is in React 19, what changes; the difference from useTransition is in useTransition in practice; keys in lists are in the key warning. The framework comparison is in frontend framework comparison.

Frequently asked questions

Does useDeferredValue replace a debounce?

No. A debounce waits a fixed interval before updating; useDeferredValue waits for nothing and leaves the timing to React.

Why is the list still slow?

Because the list component is not memoised, or because the filter is recomputed on every render. Wrap the list in memo and the computation in useMemo.

Is the deferred value always different from the real one?

No, they match as soon as React finishes the deferred render. Comparing the two is true only while the update is queued.

Can I pass a second argument?

Yes, in React 19 the second argument is the initial value used on the first render. It helps when the value arrives from outside and you want to avoid a first render with stale data.

Is it meant for network requests?

No. useDeferredValue works on rendering, not on requests: the network needs a cache, cancellation and a data library.