自动缓存更新在react apollo

时间:2018-04-02 16:27:10

标签: reactjs graphql graphql-js react-apollo

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

1 个答案:

答案 0 :(得分:2)

假设您正在使用apollo-cache-inmemory,除非您要在列表中添加项目或从列表中删除项目,否则不必使用更新。但是,请务必记住缓存的数据已规范化,并且Apollo使用__typenameid(或_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)
    }
  }
})

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