首页 > 解决方案 > 创建对象后更新 Apollo 缓存

问题描述

突变后更新 Apollo InMemoryCache的所有不同方法是什么?从文档中,我可以看到:

  1. Apollo 自动执行 的基于 ID 的更新
    • 仅针对现有对象的单个更新发生。
    • 需要一个id唯一标识每个对象的字段,或者缓存必须配置一个dataIdFromObject提供唯一标识符的功能。
  2. 通过更新功能“手动”缓存更新
    • 对多个对象的对象创建、删除或更新是必需的。
    • 涉及调用cache.writeQuery详细信息,包括应影响哪个查询以及应如何更改缓存。
  3. refetchQueries将选项传递给useMutation钩子
    • 调用代码说明应该从 API 重新获取哪些查询,Apollo 进行获取,结果替换给定查询的缓存中的任何内容。

还有其他我错过的方法,或者我对上述方法有什么误解吗?

我很困惑,因为我一直在阅读一个项目的代码,该项目使用 Apollo 进行各种突变,包括创建和删除,但我没有看到cache.writeQuery对 . 的任何调用,也没有看到refetchQueries. 在没有其中任何一个的情况下创建和删除后如何更新缓存?

在我自己对 Apollo 的有限经验中,缓存不会在对象创建或删除后自动更新,即使我定义了dataIdFromObject. 我必须自己通过编写更新函数来更新缓存。

所以我想知道是否有一些我错过了让 Apollo 为我处理它的秘密配置。

标签: graphqlapolloreact-apolloapollo-client

解决方案


创建或删除节点并让 Apollo 自动更新缓存以反映更改的唯一方法是返回包含更新的 List 字段的任何字段的父字段。例如,假设我们有这样的模式:

type Query {
  me: User
}

type User {
  id: ID!
  posts: [Post!]!
}

type Post {
  id: ID!
  body: String!
}

按照惯例,如果我们有一个添加新帖子的突变,突变字段将返回创建的帖子。

type Mutation {
  writePost(body: String!): Post!
}

但是,我们可以让它返回登录的用户(与me字段返回的内容相同):

type Mutation {
  writePost(body: String!): User!
}

通过这样做,我们使客户端能够进行如下查询:

mutation WritePost($body: String!){
  writePost(body: $body) {
    id
    posts {
      id
      body
    }
  }
}

在这里,Apollo 不仅会为所有返回的帖子创建或更新缓存,还会更新返回的 User 对象,包括帖子列表。

那么为什么不经常这样做呢?为什么 Apollo 的文档建议writeQuery在添加或删除节点时使用?

当您的架构很简单并且您使用的数据量相对较少时,上述方法将正常工作。但是,一旦您处理更多数据,返回整个父节点(包括其所有关系)可能会明显变慢且资源密集。此外,在许多应用程序中,单个突变可能会影响缓存中的多个查询。模式中的任意数量的字段都可以返回相同的节点,甚至相同的字段也可能是使用不同过滤器、排序参数等的许多不同查询的一部分。

这些因素使您不太可能希望在生产中实现此模式,但肯定有一些用例可能是一个有效的选项。


推荐阅读