document表示缓存可以在以下示例中自动更新:
{
post(id: '5') {
id
score
}
}
mutation {
upvotePost(id: '5') {
id
score
}
}
当缓存对象在列表中时,自动更新是否会在以下情况下工作?像这样:
这是一个获取评论列表的查询:
{
reviewList(model:12){
list{
reviewId
text
}
cursor
}
}
当我将其中一个评论从列表更新到服务器时,反应apollo不会自动更新缓存的评论:
mutation{
updateReview(reviewId:'1',text:'new text'){
reviewId
text
}
}
是否必须使用突变组件的update
属性来更新缓存?
答案 0 :(得分:2)
假设您正在使用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)
}
}
})
只要结果值是唯一的,您就可以以类似的方式利用任何其他字段(或字段组合)。