如何强制 Apollo 客户端将缓存数据用于详细视图页面
Posted
技术标签:
【中文标题】如何强制 Apollo 客户端将缓存数据用于详细视图页面【英文标题】:How to force Apollo Client to use cached data for detail view page 【发布时间】:2021-01-28 15:54:56 【问题描述】:我有一个基于分页游标的查询 TODOS 和带有查询 TODO 的详细信息页面,以按 ID 获取数据。 每当我转到详细视图并将 useQuery 与 TODO 查询一起使用时(其中包含与 TODOS 查询结果完全相同的数据,它仍然会尝试获取数据从服务器而不是从缓存。我怎样才能实现不从服务器获取数据(因为它已经存在),我认为 Apollo 通过 id 检测并从缓存返回但没有。有什么建议吗?
类似的问题没有这个post,但我认为这不是一个正确的方法,应该有更好的解决方案。 (希望)
这是TODOS查询:
query TODOS(
$paginationOptions: PaginationOptionsInput
)
todos(paginationOptions: $paginationOptions)
pagination
minCursor
maxCursor
sortOrder
limit
hasMoreResults
result
id
...SomeTodoFields
在详细信息页面上我有第二个查询TODO
query (
$todoId: String!
)
todo(todoId: $todoId)
id
...SomeTodoFields
【问题讨论】:
你能发布一些代码,以便我们给你一些指导吗? ApolloClient 旨在在进行任何查询之前先查看缓存,除非您明确告诉它不要使用缓存 - 您可能正在做一些意想不到的事情,导致缓存被忽略。 马上更新 如果分页TODOS查询和单个TODO查询下的字段相同,不应该从缓存中返回还是需要一些额外的配置来实现? 所以您需要检查的主要内容是从您的 TODO 查询结果返回的 __typename 以及您的 TODOS 查询的结果部分。这个想法是,如果 __typenames 与这些对象匹配,那么 ApolloClient 能够确定它们是相同的,从而执行正确的缓存查询。我的建议是将 __typename 字段添加到每个查询中,并将结果作为第一步进行比较。 __typename 有点不同,因为 TODOS 查询是分页的,它返回 paginatedTodosType 作为根 __typename 并且它有结果字段 - __typeName 数组:todoType。当我获取 TODO 查询时,我得到 __typeName: todoType 的单个对象 【参考方案1】:由于我使用 Apollo-client here。仔细阅读每一个音符,这真的很重要!我的代码示例:
cache: new InMemoryCache(
fragmentMatcher,
cacheRedirects:
Query:
todo: (_, args, getCacheKey ) =>
return getCacheKey( __typename: 'TodoType', id: args.todoId )
)
)
还发现了一些很好的相关article,您可能想检查一下。 这对我有用,希望对其他人也有帮助。 :)
【讨论】:
以上是关于如何强制 Apollo 客户端将缓存数据用于详细视图页面的主要内容,如果未能解决你的问题,请参考以下文章
GraphQL + Apollo - 如何强制进行查询,似乎正在缓存一些东西