创建对象后更新 Apollo 缓存
Update Apollo cache after object creation
Apollo的更新方式有哪些InMemoryCache after a mutation? From the docs,我可以看到:
- Id-based updates,Apollo 自动执行
- 仅对现有对象进行单次更新时发生。
- 需要一个
id
字段来唯一标识每个对象,或者必须使用 dataIdFromObject
函数配置缓存以提供唯一标识符。
- "Manual" 通过 update functions 缓存更新
- 对象创建、删除或更新多个对象时需要。
- 涉及调用
cache.writeQuery
的详细信息,包括应影响哪个查询以及应如何更改缓存。
- 将
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编辑,甚至同一个字段也可以是使用不同过滤器、排序参数等的多个不同查询的一部分。
这些因素使您不太可能希望在生产中实施此模式,但在某些用例中它可能是一个有效的选项。
Apollo的更新方式有哪些InMemoryCache after a mutation? From the docs,我可以看到:
- Id-based updates,Apollo 自动执行
- 仅对现有对象进行单次更新时发生。
- 需要一个
id
字段来唯一标识每个对象,或者必须使用dataIdFromObject
函数配置缓存以提供唯一标识符。
- "Manual" 通过 update functions 缓存更新
- 对象创建、删除或更新多个对象时需要。
- 涉及调用
cache.writeQuery
的详细信息,包括应影响哪个查询以及应如何更改缓存。
- 将
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编辑,甚至同一个字段也可以是使用不同过滤器、排序参数等的多个不同查询的一部分。
这些因素使您不太可能希望在生产中实施此模式,但在某些用例中它可能是一个有效的选项。