自动缓存更新在反应阿波罗中不起作用

Automatic cache updates do not work in react apollo

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 属性来更新缓存?

假设您正在使用 apollo-cache-inmemory,除非您要在列表中添加项目或从列表中删除项目,否则没有必要使用更新。但是,重要的是要记住缓存数据是规范化的,并且 Apollo 使用 __typenameid(或 _id)字段为任何查询的对象生成缓存键。来自文档:

The InMemoryCache normalizes your data before saving it to the store by splitting the result into individual objects, creating a unique identifier for each object, and storing those objects in a flattened data structure. By default, InMemoryCache will attempt to use the commonly found primary keys of id and _id for the unique identifier if they exist along with __typename on an object.

如果缺少 id 字段,Apollo 将不知道如何匹配查询中的数据和突变中的数据:

If id and _id are not specified, or if __typename is not specified, InMemoryCache will fall back to the path to the object in the query, such as ROOT_QUERY.allPeople.0 for the first record returned on the allPeople root query. That would make data for given type scoped for allPeople query and other queries would have to fetch their own separate objects.

幸运的是,有一个解决方法。您当然可以在服务器端将 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)
    }
  }
})

只要结果值是唯一的,您就可以以类似的方式使用任何其他字段(或字段组合)。