0Pricing
React Academy · レッスン

入力のデバウンスに使うuseDeferredValue

入力の軽快さを保ちながら、UI内の処理が遅い部分の再レンダーを遅延させます。

「入力のデバウンスに使うuseDeferredValue」はCoddyKit上の無料React Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。

ようこそ

このレッスンでは、useDeferredValueを使ってUIの重い部分の再レンダリングを遅延させながら、制御された入力の軽快な応答性を維持します。

useDeferredValueとは

useDeferredValueは値を受け取り、その遅延版を返します。緊急性の高いレンダリング中は、遅延された値が現在の値に遅れて追従するため、Reactは入力を高速に更新し、重い出力を遅延させるという2段階でUIを更新できます。
const [query, setQuery] = useState('');
const deferredQuery = useDeferredValue(query);
// query updates immediately on keystroke
// deferredQuery updates when React has capacity

重いコンポーネントへの適用

重いコンポーネントには、現在の値ではなく遅延された値を渡します。重いコンポーネントは、遅延しているdeferredQueryが変化したときだけ再レンダリングされるため、入力が速い場合は入力より遅れて更新されます。
function App() {
  const [q, setQ] = useState('');
  const dq = useDeferredValue(q);
  return (
    <>
      <input value={q} onChange={e => setQ(e.target.value)} />
      <HeavyList query={dq} /> {/* renders with deferred value */}
    </>
  );
}

古いコンテンツのインジケーターを表示する

現在の値と遅延された値を比較します。両者が異なる場合、コンテンツは古い状態なので、opacityで薄く表示したり、ローディングスピナーを表示したりできます。
const isStale = q !== dq;
<div style={{ opacity: isStale ? 0.5 : 1 }}>
  <HeavyList query={dq} />
</div>

useDeferredValueとdebounceの比較

setTimeoutベースのdebounceは、高速なマシンでも常に固定の遅延(たとえば300ミリ秒)を発生させます。useDeferredValueは適応型です。高速なデバイスではすぐにレンダリングし、低速なデバイスではカクつきを防ぐために遅延させます。

useDeferredValueとuseTransitionの比較

状態のsetterを自分で所有していてsetStateをラップできる場合はuseTransitionを使います。プロップやコンテキストから値を受け取り、その更新タイミングを制御できない場合はuseDeferredValueを使います。
// You own the state: use useTransition
startTransition(() => setTab(newTab));

// You receive the value: use useDeferredValue
const deferredProp = useDeferredValue(props.searchQuery);

React.memoとの組み合わせ

useDeferredValueで再レンダリングを効果的に省略するには、重いコンポーネントをReact.memoでラップする必要があります。これがないと、遅延された値に関係なく、親が再レンダリングするたびにコンポーネントも再レンダリングされます。
const HeavyList = React.memo(function({ query }) {
  // expensive rendering
  return <ul>{data.filter(q => ...).map(...)}</ul>;
});

初回レンダリング時の遅延値

初回レンダリングでは、遅延された値は現在の値と同じで、遅延はありません。遅延が発生するのは、再レンダリング中に現在の値と遅延された値が異なる場合だけです。

複数の遅延値

useDeferredValueは複数回呼び出して、UIの異なる重い部分をそれぞれ独立して遅延させることができます。
const deferredA = useDeferredValue(valueA);
const deferredB = useDeferredValue(valueB);

制限事項

useDeferredValueはレンダリングを速くするものではなく、単に遅延させるだけです。重いレンダリングに500ミリ秒かかる場合、UIは依然としてカクつきます。本当に大きなリストには、仮想化(react-virtual)を組み合わせてください。

理解度チェック

useDeferredValueは、通常の値を使う場合と比べて、どのようなときに効果がありますか?

まとめ

useDeferredValueは、値に遅れて追従するバージョンを返します。それを、React.memoでラップした重いコンポーネントに渡してください。deferredValue !== valueのときは、古いコンテンツであることを示すインジケーターを表示します。適応型のパフォーマンスが必要な場合は、固定遅延のdebounceよりもuseDeferredValueを優先してください。

次のレッスン

次のレッスンは、**データとコードの境界に使うSuspense**です。Suspenseを遅延読み込みやデータライブラリと組み合わせ、整ったローディング状態を作る方法を学びます。

よくある質問

「入力のデバウンスに使うuseDeferredValue」レッスンは無料ですか?

はい。「入力のデバウンスに使うuseDeferredValue」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。

「入力のデバウンスに使うuseDeferredValue」で何を学びますか?

入力の軽快さを保ちながら、UI内の処理が遅い部分の再レンダーを遅延させます。 ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

React Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「入力のデバウンスに使うuseDeferredValue」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このReact Academyレッスンでコードを書いて実行できますか?

はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 競合状態とEffectのクリーンアップ
  2. ブロッキングしないUI更新のためのuseTransition
  3. 入力のデバウンスに使うuseDeferredValue
  4. データとコードの境界に使うSuspense
← React Academyに戻る