Skip to content

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 课程总览。

用心记录每一步成长