创建对象后更新 Apollo 缓存

Update Apollo cache after object creation

Apollo的更新方式有哪些InMemoryCache after a mutation? From the docs,我可以看到:

  1. Id-based updates,Apollo 自动执行
    • 仅对现有对象进行单次更新时发生。
    • 需要一个 id 字段来唯一标识每个对象,或者必须使用 dataIdFromObject 函数配置缓存以提供唯一标识符。
  2. "Manual" 通过 update functions 缓存更新
    • 对象创建、删除或更新多个对象时需要。
    • 涉及调用 cache.writeQuery 的详细信息,包括应影响哪个查询以及应如何更改缓存。
  3. refetchQueries 选项传递给 useMutation 挂钩
    • 调用代码说明应从 API 中重新获取哪些查询,Apollo 进行获取,结果替换给定查询的缓存中的任何内容。

是否还有其他方法我错过了,或者我对上述方法有任何误解?

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

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

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

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

type Query {
  me: User
}

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

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

按照惯例,如果我们有一个 mutation 来添加一个新的 post,mutation 字段将 return 创建 post.

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

但是,我们可以用 return 登录用户代替(me 字段 returns 也是如此):

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

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

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

这里 Apollo 不仅会为所有 returned posts 创建或更新缓存,还会更新 returned 的 User 对象,包括列表posts.

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

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

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