Reactjs 如何在多个视图中处理变异后的缓存更新?
这是一个开放的问题,但希望它不会被删除 我使用的是react和apollo,尽管问题更一般 假设我的应用程序中有3个不同的视图,都使用相似(但不相同)的数据。 它们都使用单独的查询,但每个查询都使用公共操作,但返回的数据略有不同 假设我在某个地方有一个突变,它向数据中添加了一些东西(想象一下一个项目列表和一个新项目被添加) 比如说,在变异之后,我想更新缓存以反映这种变化。我正在使用读/写工具进行更新。 使用此设置,我需要更新3个查询-这将成为维护的噩梦 经过一番阅读,我觉得我做错了——我现在创建了一个查询——现在我只需要在变异后更新这个查询,我的所有视图都会自动更新。 但是问题是,这个查询现在必须下载所有3个视图组合所需的所有数据-感觉这是非常低效的,因为一些视图将获得他们永远不会使用的数据 有更好的方法吗 请注意,Reactjs 如何在多个视图中处理变异后的缓存更新?,reactjs,apollo,react-apollo,apollo-client,Reactjs,Apollo,React Apollo,Apollo Client,这是一个开放的问题,但希望它不会被删除 我使用的是react和apollo,尽管问题更一般 假设我的应用程序中有3个不同的视图,都使用相似(但不相同)的数据。 它们都使用单独的查询,但每个查询都使用公共操作,但返回的数据略有不同 假设我在某个地方有一个突变,它向数据中添加了一些东西(想象一下一个项目列表和一个新项目被添加) 比如说,在变异之后,我想更新缓存以反映这种变化。我正在使用读/写工具进行更新。 使用此设置,我需要更新3个查询-这将成为维护的噩梦 经过一番阅读,我觉得我做错了——我现在创建
read/writeFragment
将不起作用,因为它们不会更新基础查询-请检查此答案,例如:
如果你需要一个更具体的例子,请在评论中告诉我
总而言之,我认为在这个设置中,全局状态处理会更好,同时避免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
创建一篇文章
如果不使用refetchquerys
或手动更新每个查询,如何使用这些突变创建或发布帖子并更新所有3个缓存查询?
我认为真正的问题是,这些查询中的每一个都单独存储在apollo in memory cache中。听起来您已经研究并使用了更新参数,该参数可以传递给从UseMartation返回的变异函数。您可能正在使用proxy.readQuery和proxy.writeQuery来更新它(或者让这种神奇的事情在后台发生)。如果没有,这里是答案 另一种在概念上类似但更详细的方法是使用proxy.readFragment和proxy.writeFragment。您可以将类型上的一组属性指定为片段的一部分,并在出现新数据时更新该片段。很好的一点是,这个片段可以在任意数量的查询中使用,如果您更新片段,这些查询将更新
根据我的经验,这里是应该怎么做的
在
CreateDraftPost
突变的情况下:
update
函数。在这个update
函数中,您可以通过创建Post
的新片段来修改根查询posts
的缓存,然后将该片段添加到posts
中。见此:PostTitles
和Posts
都依赖于根查询Posts
(只是在查询的字段中有所不同),并且您刚刚添加到Posts
中的Post
的新片段有足够的字段,因此您的PostTitles
和Posts
应该自动反映更改CreateDraftPost
始终使用published
创建草稿,因此默认值为false
。您不需要更新与PublishedPosts
query相关的任何内容在
PublishPost
突变的情况下:
Post
(id
,published
)。通过Apollo GraphQL缓存机制,此Post
(由id
标识)将在涉及的任何查询中更新。见此:PublishedPost
查询。通过在突变调用中提供update
函数来实现这一点。在这个update
函数中,您将首先PublishedPost
的readQuery
,从返回的数据中创建一个新的Post
,最后writeQuery
将此Post添加到PublishedPost
结果中。请参阅:使用
refetchquerys
如何:
- 在
突变的情况下,仅查询CreateDraftPost
就足够了(应该相应地更新Posts
)由于PostTitles
和Posts
都依赖于相同的根查询PostTitles
,Posts
中的字段也涵盖了Posts
PostTitles
- 在
突变的情况下,我更愿意重新提取PublishPost
查询,以避免做整个PublishdPost
的事情(因为我很懒,而且我认为重新提取一个查询不会花费太多)update