自动缓存更新在 react apollo 中不起作用
Posted
技术标签:
【中文标题】自动缓存更新在 react apollo 中不起作用【英文标题】:Automatic cache updates do not work in react apollo 【发布时间】:2018-09-11 21:16:32 【问题描述】:document 表示缓存可以在以下示例中自动更新:
post(id: '5')
id
score
mutation
upvotePost(id: '5')
id
score
当缓存对象在列表中时,自动更新会在以下情况下工作吗?像这样:
这是一个获取评论列表的查询:
reviewList(model:12)
list
reviewId
text
cursor
当我将列表中的一条评论更新到服务器时,react apollo 不会自动更新缓存的评论:
mutation
updateReview(reviewId:'1',text:'new text')
reviewId
text
是否必须使用突变组件的update
属性来更新缓存?
【问题讨论】:
【参考方案1】:假设您使用的是apollo-cache-inmemory
,除非您要在列表中添加项目或从列表中删除项目,否则不需要使用更新。但是,重要的是要记住缓存数据是标准化的,并且 Apollo 利用__typename
和id
(或_id
)字段为任何查询对象生成缓存键。来自文档:
InMemoryCache 在将数据保存到存储之前对其进行规范化 通过将结果拆分为单个对象,创建一个独特的 每个对象的标识符,并将这些对象存储在展平的 数据结构。默认情况下,InMemoryCache 将尝试使用 常见的 id 和 _id 的主键作为唯一标识符 if 它们与对象上的 __typename 一起存在。
如果缺少id
字段,Apollo 将不知道如何匹配查询中的数据和突变中的数据:
如果没有指定 id 和 _id,或者如果没有指定 __typename, InMemoryCache 将回退到查询中对象的路径, 例如 ROOT_QUERY.allPeople.0 用于返回的第一条记录 allPeople 根查询。这将使给定类型的数据范围为 allPeople 查询和其他查询必须自己获取 分开的对象。
幸运的是,有一个解决方法。您当然可以在服务器端将reviewId
重命名为id
。但是,如果您希望缓存只使用 reviewId
字段,则可以将 dataIdFromObject
函数传递给您的 InMemoryCache 构造函数:
import InMemoryCache, defaultDataIdFromObject from 'apollo-cache-inmemory'
const cache = new InMemoryCache(
dataIdFromObject: object =>
switch (object.__typename)
case 'Review': return object.reviewId
default: return defaultDataIdFromObject(object)
)
只要结果值是唯一的,您就可以以类似的方式使用任何其他字段(或字段组合)。
【讨论】:
以上是关于自动缓存更新在 react apollo 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
使用`react-apollo-hooks`和`useSubscription`钩子时如何避免“自动更新”缓存
React Apollo:添加新项目时更新列表缓存(带变量)
Apollo resetStore 在 Angular 客户端中不起作用