React 速習チュートリアル

React Transitions

1. useTransitionとは?

useTransition フックは、重い更新処理が行われている間もReactアプリの応答性(レスポンシブ性)を維持するのに役立ちます。

このフックを使用すると、一部のステート(State)更新を「非緊急(non-urgent)」としてマークし、他のより緊急度の高い更新を優先的に実行させることができます。

2. トランジション(Transitions)を使用すべきタイミング

以下のようなケースでトランジションの使用を検討してください:

  • UIをフリーズさせる可能性がある低速な操作
  • 直ちに実行されなくても致命的ではない更新
  • 表示に時間がかかる検索結果の反映

3. 基本的な使用例

検索機能においてトランジションをどのように使用するかを示すシンプルな例です。

import { useState, useTransition } from 'react';

function SearchBar() {
  const [text, setText] = useState('');
  const [results, setResults] = useState('');
  const [isPending, startTransition] = useTransition();

  const handleChange = (e) => {
    // 緊急:インプットフィールドを即座に更新
    setText(e.target.value);

    // 非緊急:検索結果のステート更新をトランジションとしてマーク
    startTransition(() => {
      setResults(e.target.value);
    });
  };

  return (
    <div>
      <input value={text} onChange={handleChange} />
      {isPending ? (
        <p>読み込み中...</p>
      ) : (
        <p>「{results}」の検索結果</p>
      )}
    </div>
  );
}

この例のポイント:

  • インプットフィールドへの入力は即座に更新されます(緊急の更新)。
  • 検索結果の更新はトランジションとしてマークされます(非緊急)。
  • トランジションが保留されている間(Pending状態)、ローディングメッセージが表示されます。

4. 実践的なユースケース

低速な検索機能を想定した、より実用的な例を紹介します。

import { useState, useTransition } from 'react';

function SearchResults({ query }) {
  // 低速な検索結果のレンダリングをシミュレート
  const items = [];
  if (query) {
    for (let i = 0; i < 1000; i++) {
      items.push(<li key={i}>{query} の検索結果 - {i}</li>);
    }
  }
  return <ul>{items}</ul>;
}

function App() {
  const [input, setInput] = useState('');
  const [query, setQuery] = useState('');
  const [isPending, startTransition] = useTransition();

  const handleChange = (e) => {
    // 緊急:インプットフィールドを更新
    setInput(e.target.value);
    
    // 非緊急:検索結果のクエリ更新
    startTransition(() => {
      setQuery(e.target.value);
    });
  };

  return (
    <div>
      <input 
        type="text" 
        value={input} 
        onChange={handleChange} 
        placeholder="検索キーワードを入力..."
      />
      {isPending && <p>結果を読み込み中...</p>}
      <SearchResults query={query} />
    </div>
  );
}

この例の動作:

  • 入力フィールドに文字を打ち込むと、その変更は即座に反映されます。
  • 検索結果の更新は startTransition でラップされています。
  • 結果の更新処理中、isPendingtrue になります。
  • 結果が大量にある場合でも、UI(インプットフィールドなど)の応答性は維持されます。

5. useTransitionフックの詳細

useTransition フックは以下の2つのアイテムを返します:

  • isPending: トランジションが現在アクティブ(実行中)かどうかを判定するフラグです。
  • startTransition: ステートの更新をトランジションとしてマークするための関数です。

       注意: トランジションは「非緊急」の更新にのみ使用してください。例えば、ユーザーが入力フィールドに文字を打ち込む操作は「緊急」であるべきですが、大規模なリストをフィルタリングするような処理は「トランジション」として扱うのが最適です。