Mutation、乐观更新与回滚
Mutation 改变服务器,query 负责读取服务器状态。乐观更新的顺序必须可回滚:取消正在进行的同 key 查询、保存旧快照、写入临时结果、提交 mutation;失败时恢复快照,成功时用服务端响应或失效重取校正。
ts
const mutation = useMutation({
mutationFn: (draft: Todo) => api.createTodo(draft),
onMutate: async (draft) => {
await queryClient.cancelQueries({ queryKey: ['todos', draft.userId] })
const previous = queryClient.getQueryData<Todo[]>(['todos', draft.userId])
queryClient.setQueryData<Todo[]>(['todos', draft.userId], (items = []) => [draft, ...items])
return { previous }
},
onError: (_error, draft, context) => {
if (context?.previous) queryClient.setQueryData(['todos', draft.userId], context.previous)
},
onSettled: (_data, _error, draft) => {
return queryClient.invalidateQueries({ queryKey: ['todos', draft.userId] })
},
})临时 id、重复点击、权限拒绝和多个并发 mutation 都会挑战这个模型;不能把“界面先变了”当成写入成功。
练习
给新增评论设计乐观更新:网络失败、重复提交和服务端返回真实 id 时,分别如何处理?
下一步
完成练习后打开本章答案,再回到TanStack Query 课程总览。