Reactjs 自动缓存更新在react apollo中不起作用

Reactjs 自动缓存更新在react apollo中不起作用,reactjs,graphql,graphql-js,react-apollo,Reactjs,Graphql,Graphql Js,React Apollo,表示缓存可以在以下示例中自动更新: { post(id: '5') { id score } } mutation { upvotePost(id: '5') { id score } } 当缓存对象位于列表中时,在以下情况下自动更新是否有效?像这样: 这是一个获取评论列表的查询: { reviewList(model:12){ list{ reviewId text } cursor }

表示缓存可以在以下示例中自动更新:

{
  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
,除非您要向列表中添加项目或从列表中删除项目,否则不必使用update。但是,重要的是要记住,缓存的数据是标准化的,Apollo使用
\uu typename
id
(或
\u id
)字段为任何查询的对象生成缓存键。从文档中:

InMemoryCache会在将数据保存到存储之前对其进行规范化 通过将结果拆分为单个对象,创建唯一的 每个对象的标识符,并将这些对象存储在平面中 数据结构。默认情况下,InMemoryCache将尝试使用 唯一标识符的id和_id的常见主键,如果 它们与对象上的uuu typename一起存在

如果
id
字段缺失,Apollo将不知道如何匹配查询数据和变异数据:

如果未指定id和_id,或者未指定u 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)
    }
  }
})

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

假设您使用的是
apollo cache inmemory
,除非您在列表中添加项目或从列表中删除项目,否则不必使用update。但是,重要的是要记住,缓存的数据是标准化的,Apollo使用
\uu typename
id
(或
\u id
)字段为任何查询的对象生成缓存键。从文档中:

InMemoryCache会在将数据保存到存储之前对其进行规范化 通过将结果拆分为单个对象,创建唯一的 每个对象的标识符,并将这些对象存储在平面中 数据结构。默认情况下,InMemoryCache将尝试使用 唯一标识符的id和_id的常见主键,如果 它们与对象上的uuu typename一起存在

如果
id
字段缺失,Apollo将不知道如何匹配查询数据和变异数据:

如果未指定id和_id,或者未指定u 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)
    }
  }
})
只要结果值是唯一的,您就可以以类似的方式使用任何其他字段(或字段组合)