React Best Practices

Chapter 4 · Practice 4 of 5

Keep typing responsive with transitions and deferred values

From Performance and memoization

Why it matters

Not every update is equally urgent. Typing in a search box must feel instant; re-rendering a big results list can wait a moment.

Mark the slow update as non-urgent so React can interrupt it when the user types again:

  • Wrap the non-urgent update in startTransition, or
  • pass the value through useDeferredValue and render the slow part from the deferred copy.

In React 19.3, separate transitions render independently, so one slow transition no longer blocks unrelated ones.

Example

TSX
function Search() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query);
  const isStale = query !== deferredQuery;
  return (
    <>
      <input value={query} onChange={(e) => setQuery(e.target.value)} />
      <div style={{ opacity: isStale ? 0.6 : 1 }}>
        <Results query={deferredQuery} />
      </div>
    </>
  );
}