reactjs - 如何在多个视图中处理突变后的缓存更新?
问题描述
这更像是一个悬而未决的问题,但希望它不会被删除。
我正在使用 react 和 apollo,尽管问题更笼统。
假设我的应用中有 3 个不同的视图,它们都使用相似(但不相同)的数据。它们都使用单独的查询,但每个查询都使用通用操作,但返回的数据略有不同。
假设我在某处有一个突变,它向数据添加了一些东西(想想一个项目列表和一个正在添加的新项目)。
假设在突变后我想更新缓存以反映该更改。我正在使用 read/writeQuery 进行更新。使用此设置,我需要更新 3 个查询 - 这将成为维护的噩梦。
经过一番阅读,我认为我做错了——我现在创建了一个查询——现在我只需要在突变后更新那个单一的查询,我的所有视图都会自动更新。然而问题是这个查询现在必须下载所有 3 个视图组合所需的所有数据 - 感觉这非常低效,因为一些视图将获得他们永远不会使用的数据。
有更好的方法吗?
请注意,这read/writeFragment
不起作用,因为它们不会更新基础查询-例如检查此答案:https ://stackoverflow.com/a/50349323/2874705
如果您需要更具体的示例,请在评论中告诉我。
总而言之,我认为在这个设置中我会更好地处理全局状态并避免一起使用 apollo 缓存 - 但是我觉得被骗了,因为 apollo 承诺解决状态问题:)
编辑
这是一个具体的例子:
假设我们的 graphql 模式是这样定义的:
type Post {
id: ID!
title: String!
body: String
published: Boolean!
}
type Query {
posts(published: Boolean): [Post!]!
}
type Mutation {
createDraft(body: String!, title: String!): Post
publish(id: Int!): Post
}
现在,我们在客户端创建 3 个查询和 2 个突变
query PostTitles {
posts {
id
title
}
}
query Posts {
posts {
id
title
body
published
}
}
query PublishedPosts {
posts (published: true) {
id
title
body
published
}
}
mutation CreateDraftPost ($body: String!, $title: String!) {
createDraft(body: $body, title: $title) {
id
title
body
published
}
}
mutation PublishPost ($id:ID!) {
publish (id: $id) {
id
published
}
}
请注意createDraft
,使用默认值创建帖子false
published
。
如何使用这些突变中的任何一个来创建或发布帖子并在不使用refetchQueries
或手动更新每个查询的情况下更新所有 3 个缓存查询?我认为真正的问题是这些查询中的每一个都单独存储在 apollo 内存缓存中。
解决方案
根据我的经验,它应该是这样的。
在CreateDraftPost
突变的情况下:
- 您调用突变并传递一个
update
函数。在此函数中,您通过创建一个新片段来update
修改根查询的缓存,然后将此片段添加到. 看到这个:https ://www.apollographql.com/docs/react/data/mutations/#making-all-other-cache-updatesposts
Post
posts
- 由于
PostTitles
andPosts
all 依赖于根查询(只是查询的字段不同)并且您刚刚添加posts
的新片段具有足够的字段,因此您的and应该自动反映更改。Post
posts
PostTitles
Posts
- 因为
CreateDraftPost
总是创建一个published
默认为false
. 您不需要更新与PublishedPosts
查询相关的任何内容。
在PublishPost
突变的情况下:
- 您调用突变,返回的结果是
Post
带有更新字段 (id
,published
) 的结果。通过 Apollo GraphQL 缓存的机制,这个Post
(由 标识id
)将在它涉及的任何查询中更新。看到这个:https ://www.apollographql.com/docs/react/data/mutations/#updating-a-single-existing-entity - 但是,您需要手动更新
PublishedPost
查询。update
通过在突变调用中提供函数来做到这一点。在此update
函数中,您将首先从返回的数据readQuery
中PublishedPost
创建一个新Post
数据,最后writeQuery
将此帖子添加到PublishedPost
结果中。参考这个:https ://www.apollographql.com/docs/react/caching/cache-interaction/#combining-reads-and-writes
如何使用refetchQueries
:
- 在
CreateDraftPost
突变的情况下,仅重新获取Posts
查询应该就足够了(PostTitles
应该相应地更新),因为两者都Posts
依赖PostTitles
于相同的根查询posts
,并且其中的字段Posts
也涵盖了PostTitles
- 在
PublishPost
突变的情况下,我宁愿重新获取PublishedPost
查询以避免做整个update
事情(因为我很懒,我认为重新获取 1 个查询不会花费我太多)
推荐阅读
- asp.net-mvc - asp.net MVC 登录用户仍然路由到登录页面
- superset - 如何在超集中更改自定义仪表板的标签颜色
- kubernetes - Kubernetes 不断创建对象
- node.js - 错误:当我执行“sequelize db:migrate”时,“请手动安装 sqlite3 包”
- search - 颤振将变量传递给 SearchDelegate 类给出错误
- android - 触摸列表中的项目后防止多次触摸
- java - 在 Java 8 中是否有更简洁的方法来执行此操作 - 地图操作
- flutter - 在我的项目中,导入'package:flare_flutter/flare_actor.dart';不导入显示错误以及在 FlareActor 中?
- javascript - 搜索数据表后如何保留对数据表所做的修改
- ruby-on-rails - 我可以将不属于模型的测试数据放在哪里?