TSX
Public
Deferred Search Results with useDeferredValue
Keep a search input responsive while a larger result list updates at lower priority.
#react
#hooks
#search
#performance
TSX
'use client';
import { useDeferredValue, useMemo, useState } from 'react';
type Product = {
id: number;
name: string;
};
export function ProductSearch({ products }: { products: Product[] }) {
const [query, setQuery] = useState('');
const deferredQuery = useDeferredValue(query);
const filteredProducts = useMemo(() => {
const normalizedQuery = deferredQuery.trim().toLowerCase();
if (!normalizedQuery) {
return products;
}
return products.filter((product) =>
product.name.toLowerCase().includes(normalizedQuery),
);
}, [deferredQuery, products]);
const isUpdating = query !== deferredQuery;
return (
<section>
<input
value={query}
onChange={(event) => setQuery(event.target.value)}
placeholder="Search products"
/>
<div style={{ opacity: isUpdating ? 0.55 : 1 }}>
{filteredProducts.map((product) => (
<article key={product.id}>{product.name}</article>
))}
</div>
</section>
);
}