web-dev-qa-db-ja.com

特定のクエリとすべての変数セットのApolloクライアントキャッシュを削除する

getAllItemsクエリに基づいてフィルターされたアイテムのリストがあります。これは、フィルターとオプションによる順序付けを引数として使用します。

新しいアイテムを作成した後、渡された変数に関係なく、このクエリのキャッシュを削除します。これを行う方法がわかりません。

キャッシュの更新はオプションではないと思います。 Apolloクライアントのドキュメントで言及されているメソッド( ミューテーション後のキャッシュの更新refetchQueries and update )はすべて特定の変数セットを必要とするようですが、フィルターは複雑なオブジェクトであるため(いくつかのテキスト情報を使用して)、以前に送信された変数の特定のセットごとにキャッシュを更新する必要があります。これを行う方法がわかりません。さらに、この新しいアイテムがページ分割と順序にどのように影響するかを知っているのはサーバーだけです。

fetch-policy (たとえば、cache-and-networkに設定する)は探していないと思います。ネットワークにアクセスする場合は、新しいアイテムを作成した後で、 、リストをフィルタリングしているとき(検索する文字列を入力しているとき)は、デフォルトの動作(cache-only)のままにしておきたいです。

client.resetStoreは、すべてのタイプのクエリ(getAllItemsクエリだけでなく)のストアをリセットするため、私が探しているものではないと思います。

私はここで何かが欠けていると確信しています。

15

現在のバージョンのApolloでは、これを正式にサポートする方法はありませんが、回避策があります。

更新関数では、アイテムを作成した後、キャッシュを反復処理して、キャッシュから削除しようとしているタイプ名でキーが始まるすべてのノードを削除できます。例えば.

// Loop through all the data in our cache
// And delete any items where the key start with "Item"
// This empties the cache of all of our items and 
// forces a refetch of the data only when it is next requested.
Object.keys(cache.data.data).forEach(key => 
  key.match(/^Item/) && cache.data.delete(key)
)

これは、さまざまな変数を使用してキャッシュに何度も存在するクエリ、つまりページ付けされたクエリで機能します。

これがどのように機能するか、さらに複雑であるが少数のユースケースでより効果的に機能する実装例と代替ソリューションについて詳しく説明したMediumに関する記事を書きました。この記事では、この回答ですでに説明した概念について詳しく説明しているので、ここで共有しても問題ないと思います: https://medium.com/@martinseanhunt/how-to-invalidate-cached -data-in-apollo-and-handle-updating-paginated-queries-379e4b9e4698

3
Martin Hunt

ngrxのような

resolvers = {
    removeTask(
       parent,
       { id },
       { cache, getCacheKey }: { cache: InMemoryCache | any; getCacheKey: any }
     ) {
       const key = getCacheKey({ __typename: "Task", id });
       const { [key]: deleted, ...data } = cache.data.data;
       cache.data.data = { ...data };
       return id;
     }
}
0
Pedro Lescano