メインコンテンツにスキップ
バージョン: v18.0.0

データの古さ

データがストアに存在すると仮定すると、それでもデータの古さを考慮する必要があります。

デフォルトでは、Relayはストア内のデータを古いと見なしません(キャッシュにどれだけ長く存在していても)。ただし、データ無効化APIを使用して明示的に古いとマークされている場合、またはクエリキャッシュの有効期限を過ぎている場合は例外です。

データを古いとマークすることは、一部のデータが最新ではないことが明示的にわかっている場合に役立ちます(たとえば、ミューテーションを実行した後など)。

Relayは、ストアの更新内でデータを古いとマークするために、次のAPIを提供しています。

Relayストアのグローバル無効化

実行できる最も粗いタイプのデータ無効化は、ストア全体を無効化することです。つまり、現在キャッシュされているすべてのデータが無効化後に古いと見なされます。

ストアを無効化するには、アップデーター関数内でinvalidateStore()を呼び出すことができます。

function updater(store) {
store.invalidateStore();
}
  • invalidateStore()を呼び出すと、無効化が発生する前にストアに書き込まれた*すべて*のデータが古いと見なされ、次回評価される際にクエリを再フェッチする必要があります。
  • アップデーター関数は、ミューテーションサブスクリプション、または単なるローカルストアの更新の一部として指定できます。

ストア内の特定のデータの無効化

どのデータを無効化するかをより詳細に指定し、ストア内の*特定のレコード*のみを無効化することもできます。グローバル無効化と比較して、無効化されたレコードを参照するクエリのみが無効化後に古いと見なされます。

レコードを無効化するには、アップデーター関数内で`invalidateRecord()`を呼び出すことができます。

function updater(store) {
const user = store.get('<id>');
if (user != null) {
user.invalidateRecord();
}
}
  • `user`レコードで`invalidateRecord()`を呼び出すと、ストア内の*その*特定のユーザーが古いとマークされます。つまり、キャッシュされていて、無効化されたユーザーを参照するクエリはすべて古いと見なされ、次回評価される際に再フェッチする必要があります。
  • アップデーター関数は、ミューテーションサブスクリプション、または単なるローカルストアの更新の一部として指定できます。

データの無効化の購読

ストアまたはレコードを古いとマークするだけでは、クエリは次回評価される際に再フェッチされます。たとえば、古いクエリをレンダリングするページに次回移動したときに、データがキャッシュされていても、クエリが古いデータを参照しているため、クエリは再フェッチされます。

これは多くのユースケースで役立ちますが、無効化時にすぐにデータを再フェッチしたい場合があります。例:

  • 現在のページにすでに表示されているデータを無効化する場合。ナビゲーションが発生しないため、現在のページのクエリは再評価されないため、一部のデータが古くてもすぐに再フェッチされず、古いデータが表示されます。
  • アンマウントされていない以前のビューでレンダリングされたデータを無効化する場合。ビューがアンマウントされていないため、戻って移動してもそのビューのクエリは再評価されません。つまり、一部が古くても再フェッチされず、古いデータが表示されます。

これらのユースケースをサポートするために、Relayは`useSubscribeToInvalidationState`フックを提供しています。

function ProfilePage(props) {
// Example of querying data for the current page for a given user
const data = usePreloadedQuery(
graphql`...`,
props.preloadedQuery,
)

// Here we subscribe to changes in invalidation state for the given user ID.
// Whenever the user with that ID is marked as stale, the provided callback will
// be executed
useSubscribeToInvalidationState([props.userID], () => {
// Here we can do things like:
// - re-evaluate the query by passing a new preloadedQuery to usePreloadedQuery.
// - imperatively refetch any data
// - render a loading spinner or gray out the page to indicate that refetch
// is happening.
})

return (...);
}
  • `useSubscribeToInvalidationState`は、IDの配列とコールバックを受け取ります。これらのIDのレコードが古いとマークされるたびに、指定されたコールバックが起動されます。
  • コールバック内では、それに応じて反応し、古いデータを表示している現在のビューを再フェッチまたは更新できます。例として、`preloadedQuery`を状態に保ち、ここで新しいものを設定することにより、トップレベルの`usePreloadedQuery`を再実行できます。その時点でクエリは古いため、データがストアにキャッシュされていてもクエリは再フェッチされます。

クエリキャッシュの有効期限

さらに、クエリキャッシュの有効期限は、特定の操作(つまり、クエリと変数)をストアにすでに存在するデータで満たせるかどうか、つまりクエリのデータが古くなったかどうかに影響します。

古いクエリとは、ストアからのレコードで満たすことができ、

  • 最後にフェッチされてからの時間がクエリキャッシュの有効期限よりも長い、または
  • 無効化されたレコードが少なくとも1つ含まれているクエリです。

この古さのチェックは、新しいリクエストが行われたとき(たとえば、`loadQuery`の呼び出し)に発生します。古いデータを参照するコンポーネントは、引き続きそのデータをレンダリングできます。ただし、古いデータを使用して満たされる追加のリクエストはネットワークに送信されます。

クエリキャッシュの有効期限を設定するには、Relayストアに`queryCacheExpirationTime`オプションを指定できます。

const store = new Store(source, {queryCacheExpirationTime: 5 * 60 * 1000 });

クエリキャッシュの有効期限が指定されていない場合、古さのチェックでは、参照されているレコードが無効化されているかどうかのみが確認されます。


このページは役に立ちましたか?

いくつかの簡単な質問に答えることで、サイトの改善にご協力ください。 簡単な質問に答えてください.