コンテンツへスキップ
ドキュメント
高度な機能
SWR の理解

SWR の理解

ステートマシン

useSWR は、dataerrorisLoading、そして isValidating を、fetcher 関数の状態に応じて返します。これらの図は、SWR がいくつかのシナリオでどのように値を返すかを説明しています。

フェッチと再検証

このパターンは、データをフェッチし、後で再検証することです。

A pattern for fetch and revalidate

キーの変更

このパターンは、データをフェッチし、キーを変更して後で再検証することです。

A pattern for key change

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

このパターンは、データをフェッチし、キーを変更して後でkeepPreviousData オプションを使用して再検証することです。

A pattern for key change + previous data

フォールバック

このパターンは、データをフェッチし、後でフォールバックデータを使用して再検証することです。

A pattern for fallback

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

このパターンは、データをフェッチし、キーを変更して後でフォールバックデータを使用して再検証することです。

A pattern for key change + fallback

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

このパターンは、データをフェッチし、キーを変更して後でkeepPreviousData オプションとフォールバックデータを使用して再検証することです。

A pattern for key change + previous data + fallback

isLoading と isValidating を組み合わせた優れた UX

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

  • isValidating は、データがロードされているかどうかに関係なく、進行中のリクエストがあるときはいつでも true になります。
  • isLoading は、進行中のリクエストがあり、まだデータがロードされていない場合true になります。

簡単に言うと、isValidating を再検証が実行されているすべての時点を示すために使用し、isLoading を SWR が再検証中だが表示できるデータがないことを示すために使用できます。

📝

フォールバックデータと以前のデータは「ロードされたデータ」とは見なされません。そのため、フォールバックデータを使用するか、keepPreviousData オプションを有効にすると、表示できるデータがある可能性があります。

function Stock() {
  const { data, isLoading, isValidating } = useSWR(STOCK_API, fetcher, {
    refreshInterval: 3000
  });
 
  // If it's still loading the initial data, there is nothing to display.
  // We return a skeleton here.
  if (isLoading) return <div className="skeleton" />;
 
  // Otherwise, display the data and a spinner that indicates a background
  // revalidation.
  return (
    <>
      <div>${data}</div>
      {isValidating ? <div className="spinner" /> : null}
    </>
  );
}

An example of using the isLoading state

コード例はこちら(新しいタブで開きます)にあります。

より優れた UX のための以前のデータの返却

継続的なユーザーアクション(例:タイピング時のリアルタイム検索)に基づいてデータ取得を行う場合、以前の取得データを保持すると UX が大幅に向上します。keepPreviousData は、その動作を有効にするオプションです。簡単な検索 UI を次に示します。

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(新しいタブで開きます)にあります。

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

SWR は、コンポーネントで使用されている状態が更新された場合にのみ、再レンダリングをトリガーします。コンポーネントでdata のみを 使用する場合、SWR はisValidatingisLoading などの他のプロパティの更新を無視します。これにより、レンダリング回数が大幅に削減されます。詳細については、こちらをご覧ください。