【问题标题】:Automatic cache updates do not work in react apollo自动缓存更新在 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属性来更新缓存?

【问题讨论】:

    标签: reactjs graphql graphql-js react-apollo


    【解决方案1】:

    假设您使用的是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)
        }
      }
    })
    

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

    【讨论】:

      猜你喜欢
      • 2017-08-01
      • 2019-07-05
      • 2021-07-30
      • 2020-09-16
      • 2017-10-03
      • 2020-03-04
      • 2020-02-03
      • 2022-08-15
      • 2021-03-11
      相关资源
      最近更新 更多