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

useSWRInfinite分页时mutate的optimisticData不即时生效问题

useSWRInfinite 乐观更新不生效修复

问题根因

配置了optimisticData却不触发即时渲染的核心原因有两个:

  • 生成乐观更新数据时直接修改了原缓存对象的引用:代码里直接执行--comment._count.likedBy、comment.likedByIds.push()这类可变操作,已经污染了SWR持有的原状态,后续哪怕返回浅拷贝的对象,SWR的浅比较逻辑会判定状态未发生实质变更,不会触发即时重渲染。
  • 普通useSWR的缓存是单值结构,而useSWRInfinite的缓存是分页嵌套的二维数组结构,对引用变更的检测更严格,直接修改嵌套属性的写法在单值场景下可能碰巧生效,但在分页场景下会被状态比对拦截。

修复方案

把乐观数据生成逻辑改成全程不可变更新,绝对不要直接修改原data下的任何嵌套对象,同时补充错误回滚配置避免请求失败后UI状态异常,修复后的完整代码如下:

const { data, error, isValidating, mutate, size, setSize } = useSWRInfinite<CommentType[]>(
   (index) => `/api/comment?postId=${postId}&currentPage=${index + 1}`,
   fetcher,
   { revalidateFirstPage: false }
);

const likeCommentHandler = async (commentId: string, dislike: boolean) => {
  // 所有修改基于拷贝生成新值,不触碰原状态引用
  const optimisticData = data?.map((comments) => 
    comments.map((comment) => {
      if (comment.id !== commentId) return comment;
      // 针对目标评论生成全新对象,所有嵌套属性都做拷贝
      return {
        ...comment,
        _count: {
          ...comment._count,
          likedBy: dislike ? comment._count.likedBy - 1 : comment._count.likedBy + 1
        },
        likedByIds: dislike 
          ? comment.likedByIds.filter(id => id !== session!.user.id)
          : [...comment.likedByIds, session!.user.id]
      }
    })
  );

  mutate(
    async (currentData) => {
      const { data: result } = await axios.post("/api/likeComment", {
        commentId,
        userId: session?.user.id,
        dislike,
      });

      return currentData?.map((comments) =>
        comments.map((comment) => 
          comment.id === result.comment.id ? result.comment : comment
        )
      );
    },
    {
      optimisticData,
      revalidate: false,
      populateCache: true,
      // 请求失败自动回滚到原状态,避免UI和服务端数据不一致
      rollbackOnError: true
    }
  );
};

额外注意事项

  • 所有SWR相关的状态更新都要遵循不可变数据原则,任何嵌套属性的修改都要生成对应的新对象、新数组,不要直接修改原状态的属性值。
  • 如果后续需要跨页更新评论,只要保证optimisticData和异步更新返回值的二维数组结构,和原缓存的分页长度、顺序完全一致,就可以正常触发渲染。

内容的提问来源于stack exchange,提问作者Janghan Park

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 09:27:10