Apollo GraphQL 客户端:如何区分乐观响应和真实响应到 watchQuery
Apollo GraphQL client: how to distinguish an optimistic response from a real response into a watchQuery
问题是关于突变、乐观响应和 watchQuery 的交互。
我有一个突变 "myMutation",它有一个 "optimisticResponse" 和一个已实现的 "update" 函数。
每次我进行突变查询时,"update" 函数都会被调用两次,第一次使用乐观响应数据,第二次使用真实数据。一切正常,如文档中所述。
进入我的 "update" 函数,我通过使用 readQuery/writeQuery 方法修改 "myQuery" 缓存数据。
每次我修改 "myQuery" 缓存数据时都会调用 watchQuery(基于 "myQuery")订阅。一切正常,如文档中所述。
但问题是我无法在我的 watchQuery 中区分我收到的是乐观响应数据还是真实响应数据。这对我来说至关重要,因为反应必须不同,因为有价值的数据部分只能由服务器提供。
当我收到一个乐观的响应时,我应该显示一个具有特殊样式的 GUI 元素,并且我应该禁止与它进行任何交互,直到我收到一个真正的响应。
很遗憾,我无法解决这个问题。乍一看,乐观的反应和真实的反应没有区别。我在谷歌上搜索了很多,但没有找到解决方案。我唯一的想法是在我的 GraphQL 数据中添加一个特殊字段,该字段将显示是否从服务器收到响应。但是它看起来很丑,而且闻起来很臭。我相信,一定有一个简单正确的方法来克服这个问题。
也许有更简单的方法或者将来会有,但这是我所知道的。
optimisticResponse
中的数据仅在第一次调用更新时提供。这是您可以标记您的更新函数它正在处理乐观数据的地方。你可以把任何你想要的数据放在那里。我把 isOptimistic: true,
.
为了解决 watchQuery
问题,我建议您使用 apollo-link-state
将一个或多个客户端专用字段添加到您的数据模型中应该知道乐观更新插入的区域显示器。不要在您的变异查询中包含 isOptimistic
,这样您就知道它来自服务器而不是乐观响应,如果它不是真的,则强制它为假。看这个例子:
const SUBMIT_COMMENT_MUTATION = gql`
mutation submitComment($repoFullName: String!, $commentContent: String!) {
submitComment(repoFullName: $repoFullName, commentContent: $commentContent) {
postedBy {
login
html_url
}
createdAt
content
}
}
`;
const CommentsPageWithMutations = ({ currentUser }) => (
<Mutation mutation={SUBMIT_COMMENT_MUTATION}>
{(mutate) => (
<CommentsPage
submit={(repoFullName, commentContent) =>
mutate({
variables: { repoFullName, commentContent },
optimisticResponse: {
__typename: 'Mutation',
submitComment: {
__typename: 'Comment',
postedBy: currentUser,
createdAt: new Date(),
content: commentContent,
isOptimistic: true, // Only provided to update on the optimistic call
},
},
update: (proxy, { data: { submitComment } }) => {
// Make sure CommentAppQuery includes isOptimistic for each comment added by apollo-link-state
// submitComment.isOptimistic will be undefined here if it's from the server
const newComment = {
...submitComment,
isOptimistic: submitCommit.isOptimistic ? true : false,
};
// Read the data from our cache for this query.
const data = proxy.readQuery({ query: CommentAppQuery });
// Add our comment from the mutation to the end.
data.comments.push(newComment);
// Write our data back to the cache.
proxy.writeQuery({ query: CommentAppQuery, data });
},
})
}
/>
)}
</Mutation>
);
我无法通过仅在乐观响应上添加 属性 来使它在 Apollo 3.X 上运行,属性 被剥夺了。为了让它工作,我必须向查询添加一个局部变量。
fragment object on Object {
id
isOptimistic @client
...
一旦完成,我就可以将 local-only 标记添加到我的乐观响应中。
const optimisticResponse = {
object: {
id: "temp-id",
isOptimistic: true,
...
}
}
问题是关于突变、乐观响应和 watchQuery 的交互。
我有一个突变 "myMutation",它有一个 "optimisticResponse" 和一个已实现的 "update" 函数。
每次我进行突变查询时,"update" 函数都会被调用两次,第一次使用乐观响应数据,第二次使用真实数据。一切正常,如文档中所述。
进入我的 "update" 函数,我通过使用 readQuery/writeQuery 方法修改 "myQuery" 缓存数据。
每次我修改 "myQuery" 缓存数据时都会调用 watchQuery(基于 "myQuery")订阅。一切正常,如文档中所述。
但问题是我无法在我的 watchQuery 中区分我收到的是乐观响应数据还是真实响应数据。这对我来说至关重要,因为反应必须不同,因为有价值的数据部分只能由服务器提供。 当我收到一个乐观的响应时,我应该显示一个具有特殊样式的 GUI 元素,并且我应该禁止与它进行任何交互,直到我收到一个真正的响应。
很遗憾,我无法解决这个问题。乍一看,乐观的反应和真实的反应没有区别。我在谷歌上搜索了很多,但没有找到解决方案。我唯一的想法是在我的 GraphQL 数据中添加一个特殊字段,该字段将显示是否从服务器收到响应。但是它看起来很丑,而且闻起来很臭。我相信,一定有一个简单正确的方法来克服这个问题。
也许有更简单的方法或者将来会有,但这是我所知道的。
optimisticResponse
中的数据仅在第一次调用更新时提供。这是您可以标记您的更新函数它正在处理乐观数据的地方。你可以把任何你想要的数据放在那里。我把 isOptimistic: true,
.
为了解决 watchQuery
问题,我建议您使用 apollo-link-state
将一个或多个客户端专用字段添加到您的数据模型中应该知道乐观更新插入的区域显示器。不要在您的变异查询中包含 isOptimistic
,这样您就知道它来自服务器而不是乐观响应,如果它不是真的,则强制它为假。看这个例子:
const SUBMIT_COMMENT_MUTATION = gql`
mutation submitComment($repoFullName: String!, $commentContent: String!) {
submitComment(repoFullName: $repoFullName, commentContent: $commentContent) {
postedBy {
login
html_url
}
createdAt
content
}
}
`;
const CommentsPageWithMutations = ({ currentUser }) => (
<Mutation mutation={SUBMIT_COMMENT_MUTATION}>
{(mutate) => (
<CommentsPage
submit={(repoFullName, commentContent) =>
mutate({
variables: { repoFullName, commentContent },
optimisticResponse: {
__typename: 'Mutation',
submitComment: {
__typename: 'Comment',
postedBy: currentUser,
createdAt: new Date(),
content: commentContent,
isOptimistic: true, // Only provided to update on the optimistic call
},
},
update: (proxy, { data: { submitComment } }) => {
// Make sure CommentAppQuery includes isOptimistic for each comment added by apollo-link-state
// submitComment.isOptimistic will be undefined here if it's from the server
const newComment = {
...submitComment,
isOptimistic: submitCommit.isOptimistic ? true : false,
};
// Read the data from our cache for this query.
const data = proxy.readQuery({ query: CommentAppQuery });
// Add our comment from the mutation to the end.
data.comments.push(newComment);
// Write our data back to the cache.
proxy.writeQuery({ query: CommentAppQuery, data });
},
})
}
/>
)}
</Mutation>
);
我无法通过仅在乐观响应上添加 属性 来使它在 Apollo 3.X 上运行,属性 被剥夺了。为了让它工作,我必须向查询添加一个局部变量。
fragment object on Object {
id
isOptimistic @client
...
一旦完成,我就可以将 local-only 标记添加到我的乐观响应中。
const optimisticResponse = {
object: {
id: "temp-id",
isOptimistic: true,
...
}
}