如何用RTK Query实现乐观更新?我的Twitter克隆项目遇阻
修复RTK Query乐观更新不生效的问题
问题1:getPosts查询参数类型不匹配
你定义getPosts为build.query<Posts[],void>,但实际queryFn接收了currUserId作为参数,导致RTK Query无法正确匹配缓存条目,updateQueryData找不到要更新的缓存数据。
修复代码:
getPosts: build.query<Posts[], string>({ async queryFn(currUserId): Promise<any> { try { let followingsArr = await getFollowingArrFirebase(currUserId); let tweetsArr: {}[] = []; const q = query(collection(db, 'tweets'), where("creatorId", "in", followingsArr)) tweetsArr = await getDataFirebase(q) return { data: tweetsArr } } catch (err: any) { return { error: err } } }, providesTags: ['Posts'] })
问题2:乐观更新未实现点赞切换逻辑
当前乐观更新只处理了添加点赞的情况,但updateDataFirebase实际是切换点赞状态(已点赞则取消,未点赞则添加),乐观更新需要同步这个逻辑。
问题3:likeTweet未等待Firebase操作完成
原代码中updateDataFirebase是异步函数,但未使用await,导致queryFn直接返回结果,可能在Firebase操作完成前就触发queryFulfilled,影响错误回滚逻辑。
修复likeTweet的完整代码:
likeTweet: build.mutation({ async queryFn({ id, currUserId }): Promise<any> { try { let likedDocRef = doc(db, `tweets/${id}`); // 等待Firebase更新完成 await updateDataFirebase(likedDocRef, 'likedBy', currUserId) return { data: 'ok' } } catch (err) { return { error: err } } }, async onQueryStarted({ id, currUserId }, { dispatch, queryFulfilled }) { // 传入getPosts的查询参数currUserId,匹配正确缓存 const patchResult = dispatch( apiSlice.util.updateQueryData<Posts[], string>('getPosts', currUserId, (draft: Posts[]) => { const post = draft.find(post => post.id === id) if (post) { // 同步切换点赞逻辑 const userIdIndex = post.likedBy.indexOf(currUserId); if (userIdIndex !== -1) { post.likedBy.splice(userIdIndex, 1); } else { post.likedBy.push(currUserId); } } }) ) try { await queryFulfilled } catch { // 更新失败时回滚乐观更新 patchResult.undo() } } })
额外检查点
- 确保组件调用
useGetPostsQuery时传入了正确的currUserId参数,保证updateQueryData能定位到对应缓存。 - 确认
Posts类型中likedBy为数组类型(如string[]),避免类型错误导致更新失效。
内容的提问来源于stack exchange,提问作者H.b
相关产品推荐
相关产品推荐

