【问题标题】:Deleting Apollo Client cache for a given query and every set of variables删除给定查询和每组变量的 Apollo 客户端缓存
【发布时间】:2018-07-13 18:09:19
【问题描述】:

我有一个基于 getAllItems 查询的过滤项目列表,该查询将过滤器和按选项排序作为参数。

创建新项目后,我想删除此查询的缓存,无论传递了什么变量。我不知道该怎么做。

我不认为更新缓存是一种选择。 Apollo 客户端文档中提到的方法(Updating the cache after a mutationrefetchQueries and update)似乎都需要一组给定的变量,但由于过滤器是一个复杂的对象(带有一些文本信息),我需要为每个给定的更新缓存之前提交的一组变量。我不知道该怎么做。另外,只有服务器知道这个新项目如何影响分页和排序。

我不认为fetch-policy(例如将其设置为cache-and-network)是我正在寻找的,因为如果在创建新项目后访问网络是我想要的,当我只是过滤列表(键入要搜索的字符串),我想保持默认行为(cache-only)。

client.resetStore 会为所有类型的查询(不仅是 getAllItems 查询)重置存储,所以我认为这也不是我想要的。

我很确定我在这里遗漏了一些东西。

【问题讨论】:

  • 我不太清楚您的需求。但似乎将 fetchPolicy 用于 getAllItems 查询,会强制所有搜索来自服务器
  • 如果您在突变的update 选项中使用cache.modfiy,它将为它为getAllItems 字段缓存的所有参数变体调用您的回调函数,允许您删除已删除的他们中的任何一个项目。

标签: graphql react-apollo apollo-client


【解决方案1】:

在当前版本的 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

【讨论】:

  • "... and // 仅在下次请求数据时才强制重新获取数据。"。这与我想要实现的目标完全相反。 IE。有没有办法在删除时执行同样的操作并强制重新获取数据?
  • 我试过了,但是在缓存被删除后,我的<Query> 组件重新加载时没有数据(在data.items = [.. my items..] 之前,在缓存被删除之后data.items = undefined)。错误和加载都是错误的。所以 Query 组件没有正确地从 graphql 服务重新加载数据。
【解决方案2】:

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;
     }
}

【讨论】:

【解决方案3】:

这对我有用(需要 apollo 2 的缓存驱逐功能) - 从缓存中清除与正则表达式匹配的查询

清除缓存后查询将自动重新获取,无需手动触发重新获取(如果您使用 Angular:gql.watch().valueChanges 将执行 xhr 请求并发出新值)

export const deleteQueryFromCache = (cache: any, matcher: string | RegExp): void => {
    const rootQuery = cache.data.data.ROOT_QUERY;
    Object.keys(rootQuery).forEach(key => {
        if (key.match(matcher)) {
            cache.evict({ id: "ROOT_QUERY", fieldName: key })
        }
    });
}

【讨论】:

    猜你喜欢
    • 2020-11-27
    • 2018-12-15
    • 2020-11-21
    • 2021-04-21
    • 2017-03-18
    • 2021-06-10
    • 2020-01-23
    • 2019-11-02
    • 2021-04-13
    相关资源
    最近更新 更多