graphql - 创建对象后更新 Apollo 缓存
问题描述
突变后更新 Apollo InMemoryCache的所有不同方法是什么?从文档中,我可以看到:
- Apollo 自动执行
的基于 ID 的更新
- 仅针对现有对象的单个更新发生。
- 需要一个
id
唯一标识每个对象的字段,或者缓存必须配置一个dataIdFromObject
提供唯一标识符的功能。
- 通过更新功能“手动”缓存更新
- 对多个对象的对象创建、删除或更新是必需的。
- 涉及调用
cache.writeQuery
详细信息,包括应影响哪个查询以及应如何更改缓存。
refetchQueries
将选项传递给useMutation
钩子- 调用代码说明应该从 API 重新获取哪些查询,Apollo 进行获取,结果替换给定查询的缓存中的任何内容。
还有其他我错过的方法,或者我对上述方法有什么误解吗?
我很困惑,因为我一直在阅读一个项目的代码,该项目使用 Apollo 进行各种突变,包括创建和删除,但我没有看到cache.writeQuery
对 . 的任何调用,也没有看到refetchQueries
. 在没有其中任何一个的情况下创建和删除后如何更新缓存?
在我自己对 Apollo 的有限经验中,缓存不会在对象创建或删除后自动更新,即使我定义了dataIdFromObject
. 我必须自己通过编写更新函数来更新缓存。
所以我想知道是否有一些我错过了让 Apollo 为我处理它的秘密配置。
解决方案
创建或删除节点并让 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
在添加或删除节点时使用?
当您的架构很简单并且您使用的数据量相对较少时,上述方法将正常工作。但是,一旦您处理更多数据,返回整个父节点(包括其所有关系)可能会明显变慢且资源密集。此外,在许多应用程序中,单个突变可能会影响缓存中的多个查询。模式中的任意数量的字段都可以返回相同的节点,甚至相同的字段也可能是使用不同过滤器、排序参数等的许多不同查询的一部分。
这些因素使您不太可能希望在生产中实现此模式,但肯定有一些用例可能是一个有效的选项。
推荐阅读
- sql - 如果两个表是内连接的,输出会是什么?
- python - Flask 不显示散点图
- java - 没有直接的方法
(Ljava/lang/reflect/Method;ILretrofit2/Converter;)V 在类 Lretrofit2/ParameterHandler$Body - javascript - 如何迭代 mongoose 查询对象并在其中添加值
- flutter - Flutter Future vs Completer
- firebase - 是否可以在飞镖中链接流?
- angular - 如何将数组存储在本地存储角度?
- postgresql - 如何将一个表行拆分为多个子表?
- python - 使用没有写入任何内容的 os.listdir 时如何跳过文件
- php - Yii2 - 将子数据保留在 uclead 表格输入中父相关下拉列表的选择选项中