bhylu.com

Advertisements

React useDeferredValue

Use a deferred value when a slower view can temporarily show an older query with honest feedback.

How it works

useDeferredValue gives React permission to keep a previous value while a lower-priority render catches up. The input itself should still use the current query. Here a filtered item list uses the deferred query and exposes whether it is behind. There is no fixed debounce interval and no promise that a network request will be reduced. The demo is small, so the stale state may be brief or invisible.

Run the code

Use a separate empty lab folder with Node 22.12+ in the 22 series. Save the files below using their displayed paths; browsers may download only the basename, so create src, public or tests folders as listed. The pinned project uses React and React DOM 19.3.1 with Vite 7.3.1. Run npm install, then npm run dev and open the local address Vite prints. React examples do not run in Bhylu’s current playground.

No Apache, MySQL or change to Bhylu’s server configuration is needed. These are local teaching projects, not a publishing package. Keep generated dependencies and lockfiles in your own lab. Review the project setup.

Example

src/main.jsx

import React, { StrictMode, useState, useMemo, useDeferredValue } from 'react';
import { createRoot } from 'react-dom/client';
import './style.css';

const names = ['Market basket', 'Folding stool', 'Desk lamp'];
function App() {
  const [query, setQuery] = useState('');
  const deferred = useDeferredValue(query);
  const matches = useMemo(
    () => names.filter((name) => name.toLowerCase().includes(deferred.toLowerCase())),
    [deferred],
  );
  return (
    <main>
      <h1>Neighbourhood lending desk</h1>
      <label>
        Find equipment
        <input value={query} onChange={(event) => setQuery(event.target.value)} />
      </label>
      <p aria-live="polite">
        {query !== deferred ? 'Updating results' : 'Results current'}
      </p>
      <ul>
        {matches.map((name) => (
          <li key={name}>{name}</li>
        ))}
      </ul>
      <output>{matches.length} matches</output>
    </main>
  );
}

createRoot(document.getElementById('root')).render(
  <StrictMode>
    <App />
  </StrictMode>,
);

Expected result

Typing lamp keeps the input current and eventually leaves the desk lamp as the only result.

The memoized calculation depends on deferred, not query. This makes the intended slow boundary explicit. For a genuinely expensive child, memoization can let React reuse earlier work while urgent input updates. Measure before adding that complexity. A search API still needs cancellation, caching and error handling; deferring a value is not a data-fetching policy.

For API contracts and version differences, use React’s official documentation.

Advertisements