创建对象后更新Apollo缓存

时间:2019-10-15 21:14:26

标签: graphql apollo react-apollo apollo-client

在突变后更新阿波罗InMemoryCache的所有不同方式有哪些? From the docs,我可以看到:

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

还有其他我想念的方式吗,还是我对上述方法有误解?

我很困惑,因为我一直在阅读一个使用Apollo进行各种变异(包括创建和删除)的项目的代码,但是我看不到对cache.writeQuery的任何调用,也没有看到对{ refetchQueries。在没有创建和删除任何内容之后,如何更新缓存?

根据我自己在Apollo方面的有限经验,即使我定义了dataIdFromObject,也不会在对象创建或删除后自动更新缓存。我必须自己编写更新功能来更新缓存。

所以我想知道是否缺少让Apollo替我处理的秘密配置。

1 个答案:

答案 0 :(得分:1)

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

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

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

这些因素使得您不太可能希望在生产中实现这种模式,但是在某些用例中,它可能是有效的选择。