当使用 Apollo 的 subscription 监听数据变化时,使用了 subscribeToMore 方法,但可能会出现 updateQuery 方法没有正确传递 key args 参数的问题。
解决方法是在 updateQuery 方法中手动传递 key args 参数,如下所示:
const subscription = gql`
subscription {
newPost {
id
content
}
}
`;
const POSTS_QUERY = gql`
query getPosts($postId: Int!) {
posts(where: {id: {_eq: $postId}}) {
id
content
}
}
`;
const SUBSCRIBE_TO_NEW_POSTS = gql`
subscription {
newPost {
id
content
}
}
`;
const Post = ({ post }) => (
{post.content}
);
const Posts = ({ postId }) => {
const { data, loading, subscribeToMore } = useQuery(POSTS_QUERY, {
variables: { postId },
});
useEffect(() => {
const unsubscribe = subscribeToMore({
document: SUBSCRIBE_TO_NEW_POSTS,
updateQuery: (prev, { subscriptionData }) => {
if (!subscriptionData.data) return prev;
const newPost = subscriptionData.data.newPost;
// Use `postId` variable to filter and update the correct post.
// Otherwise, every post in the cache will be updated.
const update = {
posts: [
...(prev.posts || []),
...(post.id === newPost.id ? [newPost] : []),
],
};
return update;
},
variables: { postId }, // <-- Manually pass the `postId` variable.
});
return unsubscribe;
}, [postId, subscribeToMore]);
if (loading) return Loading...
;
const post = data.posts[0];
return (
);
};
在上面的示例中,需要手动传递 postId 变量到 updateQuery 函数中。
这会告诉 Apollo 在缓存中找到与当前 postId 匹配的 post,并更新它,而不是更新所有的 post。