React中useQuery在mutation执行后未拉取最新数据如何解决?
问题原因
Apollo Client 默认开启了缓存优先的查询策略,useQuery 会优先读取本地缓存的数据。你执行提交评论的 mutation 后,没有主动更新对应 query 的缓存,也没有触发重新拉取接口,因此 useQuery 返回的始终是旧的缓存数据。
修复方案
你可以根据实际业务需求选择以下任意一种方案:
方案1:手动触发 refetch 重新拉取数据
从 useQuery 中解构出 refetch 方法,在 mutation 执行成功后主动调用触发重新拉取:
// 解构refetch方法 const { error: error2, loading: loading2, data: data2, refetch: refetchPost } = useQuery( GET_POST_BY_ID, { variables: { postid: item.id, }, }, ); const doComment = () => { commentPost({ variables: { postId: item.id, userEmail: email, comment: inputComment, }, }) .then(({ data }) => { setInputComment(''); // 新增调用refetch refetchPost(); console.log('success'); }) .catch((e) => { console.log('not success'); }); };
方案2:配置 mutation 的 refetchQueries 自动刷新
在调用 mutation 时通过 refetchQueries 指定需要自动重新拉取的查询,无需手动调用 refetch:
const doComment = () => { commentPost({ variables: { postId: item.id, userEmail: email, comment: inputComment, }, // 新增refetchQueries配置 refetchQueries: [ { query: GET_POST_BY_ID, variables: { postid: item.id } } ] }) .then(({ data }) => { setInputComment(''); console.log('success'); }) .catch((e) => { console.log('not success'); }); };
方案3:手动更新缓存(性能最优,无需额外发请求)
如果你的 mutation 接口返回了新增的评论数据,可以直接更新Apollo本地缓存,无需额外发起查询请求:
const doComment = () => { commentPost({ variables: { postId: item.id, userEmail: email, comment: inputComment, }, // 新增update配置更新缓存 update: (cache, { data: mutationResult }) => { // 读取缓存中已有的帖子数据 const existingPost = cache.readQuery({ query: GET_POST_BY_ID, variables: { postid: item.id } }); // 把新评论追加到评论列表,字段名需和你的GraphQL schema定义一致 const updatedPost = { ...existingPost, post: { ...existingPost.post, comments: [...existingPost.post.comments, mutationResult.commentPost] } }; // 把更新后的数据写回缓存 cache.writeQuery({ query: GET_POST_BY_ID, variables: { postid: item.id }, data: updatedPost }); } }) .then(({ data }) => { setInputComment(''); console.log('success'); }) .catch((e) => { console.log('not success'); }); };
注意事项
注意检查你的 GET_POST_BY_ID 和 COMMENT_POST 两个查询的变量名、返回字段名是否和后端定义的GraphQL schema完全一致,大小写不匹配也会导致缓存匹配失败出现数据不更新的问题。
内容的提问来源于stack exchange,提问作者Zeus
相关产品推荐
相关产品推荐

