You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 15:15:33