Skip to content
ドキュメント
高度な使い方
SWR を理解する

SWR を理解する

状態機械

useSWRdataerrorisLoadingisValidatingfetcher 関数の状態に応じて返します。これらの図は SWR がそれぞれでどのように値を返すのかを示しています。

フェッチして再検証する

これはフェッチして再検証するパターンです。

フェッチと再検証のパターン

キーの変更

これはフェッチした後にキーを変更し、さらにその後再検証するパターンです。

キーが変更されたパターン

キーの変更と以前のデータ

これはフェッチした後にキーを変更し再検証するのを keepPreviousData オプション付きで行うパターンです。

キーの変更を keepPreviousData オプションありで行うパターン

フォールバック

これはフェッチした後に再検証するのをフォールバックデータと一緒に行うパターンです。

フォールバックのパターン

キーの変更とフォールバック

これはフェッチした後にキーを変更し再検証するのをフォールバックデータと一緒に行うパターンです。

キーの変更をフォールバックありで行うパターン

キーの変更と以前のデータとフォールバック

これはフェッチした後にキーを変更し再検証するのを keepPreviousData オプションとフォールバックデータと一緒に行うパターンです。

キーの変更を keepPreviousData オプションとフォールバックありで行うパターン

よりよい UX のために isLoading と isValidating を組み合わせる

既存の isValidating の値と比較して、isLoading はより一般的なローディングのための UX に役に立つ新しいプロパティです。

  • isValidating は実行中のリクエストがある場合に データがロード済みかどうかに関わらず true になります
  • isLoading は実行中のリクエストがあり ロード済みのデータがまだない場合true になります

わかりやすく言うと、isValidating は実行中の再検証が存在する場合全てで、isLoading は SWR が再検証中だけど表示するためのデータがない場合に使えます。

📝

フォールバックデータと以前のデータ (previous data) は "ロードされたデータ" とは扱われません。そのため、フォールバックデータや keepPreviousData オプションを使う場合には、表示するためのデータがあるかもしれません。

function Stock() {
  const { data, isLoading, isValidating } = useSWR(STOCK_API, fetcher, {
    refreshInterval: 3000
  });
 
  // 初期データのローディング中の場合には、表示するためのデータはありません
  // そのため、スケルトンの表示を返します
  if (isLoading) return <div className="skeleton" />;
 
  // そうでなければ、データとバックグラウンドで再検証中であることを示す
  // UI を表示します
  return (
    <>
      <div>${data}</div>
      {isValidating ? <div className="spinner" /> : null}
    </>
  );
}

isLoading を使った例

こちら (opens in a new tab) から実際のコードを確認できます。

よりよいユーザー体験のために以前のデータを返す

キー入力に応じたリアルタイム検索など継続的なユーザーアクションをベースにしたデータ取得を行う時、以前のデータを維持することによりユーザー体験を改善できます。keepPreviousData はこれを可能にするオプションです。これはシンプルな検索の例です。

function Search() {
  const [search, setSearch] = React.useState('');
 
  const { data, isLoading } = useSWR(`/search?q=${search}`, fetcher, {
    keepPreviousData: true
  });
 
  return (
    <div>
      <input
        type="text"
        value={search}
        onChange={(e) => setSearch(e.target.value)}
        placeholder="Search..."
      />
 
      <div className={isLoading ? "loading" : ""}>
        {data?.products.map(item => <Product key={item.id} name={item.name} />)
      </div>
    </div>
  );
}

keepPreviousData が有効にされている場合、SWR のキーが変わり新しいデータの取得が開始された場合にも以前のキーに対応するデータが返されます。

keepPreviousData が有効な場合には以前の検索結果が維持されます

この例のコードはこちらです: https://codesandbox.io/s/swr-keeppreviousdata-fsjz3m (opens in a new tab).

パフォーマンスのための依存収集

SWR はコンポーネントで使われているデータが更新された場合のみ再レンダリングします。コンポーネントの中で data しか使っていない場合、SWR は isValidatingisLoading のプロパティの更新を無視します。これはレンダリングの回数を減らします。詳細については こちら