値の更新を遅延させ、UIが重い場合でも古い値を表示し続ける。useTransitionとは異なり、値を渡すだけで制御できる。
const deferredValue = useDeferredValue(value)
const deferredQuery = useDeferredValue(query); // string
// deferredQuery はQueryが変わっても少し遅れて更新されるimport { useState, useDeferredValue, memo } from 'react';
// 重いリストコンポーネント
const HeavyList = memo(({ query }: { query: string }) => {
// 10000件のフィルタリング(重い処理)
const items = Array.from({ length: 10000 }, (_, i) => `item-${i}`)
.filter(item => item.includes(query));
return <ul>{items.slice(0, 20).map(i => <li key={i}>{i}</li>)}</ul>;
});
function App() {
const [query, setQuery] = useState('');
// queryが変わっても、重いレンダーが終わるまで古い値を使う
const deferredQuery = useDeferredValue(query);
return (
<div>
{/* 入力欄は即座に更新 */}
<input value={query} onChange={e => setQuery(e.target.value)} />
{/* HeavyList はdeferredQueryで遅延更新 */}
<HeavyList query={deferredQuery} />
</div>
);
}useTransitionは「いつ更新するか」を制御し、useDeferredValueは「何を遅延させるか」を制御する。コントロールできない外部の値(propsなど)の遅延にはuseDeferredValueが適している。