Redux RTK乐观更新触发Immer错误,请求排查违规原因
问题分析与解决
核心错误原因:你的
getRepliesByIdQuery定义的返回类型是IPost(单个帖子对象),但实际接口${PostPath}/${id}/replies返回的应该是回复数组(IPost[])。这就导致updateQueryData里的draft是数组类型,而你用Object.assign(draft, body)试图把一个对象合并到数组上,完全违反了Immer对数组的修改规则——数组只能通过修改索引、length或者调用数组方法(比如push、splice)来更新,不能直接用Object.assign合并对象。两步修正:
- 修正Query的返回类型:
getRepliesById: builder.query<IPost[], string>({ // 把IPost改成IPost[] query: (id: string) => `${PostPath}/${id}/replies`, }), - 修正乐观更新的修改逻辑:把新回复对象添加到数组里,而不是用Object.assign:
const patchResult = dispatch( resourcesApi.util.updateQueryData('getRepliesById', body.parent, (draft) => { draft.push(body); // 直接push新回复到数组 }) )
- 修正Query的返回类型:
额外优化(可选):如果你的POST接口会返回创建成功的完整reply对象,也可以在
queryFulfilled之后用返回结果替换乐观更新的临时数据,确保数据一致性:try { const { data: newReply } = await queryFulfilled; // 找到之前乐观添加的项并替换成真实返回的数据 const index = draft.findIndex(item => item.id === body.id); // 假设body有临时id或其他标识 if (index !== -1) { draft[index] = newReply; } } catch { patchResult.undo(); // 请求失败时撤销乐观更新 }
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

