译零 TransZero · TanStack Query v4 中文文档
主站

乐观更新 Optimistic Updates

在执行修改之前,当你"乐观"地打算进行更新时,修改有可能失败(可能性非零)。 在大多数失败的情况下,你可以轻松地为查询触发重新获取,使其恢复到真正的和服务器一致的状态。 但是在某些情况下,重新获取可能没法正确的工作,修改可能代表某种服务器端的问题,从而无法进行。 在这种情况下,你可以选择回滚更新。

为此,useMutation 的 onMutate 回调允许返回一个特定值,该值稍后将作为最后一个参数传递给 onError 和 onSettled 处理--在大多数情况下,以这种方式来传递一个回滚函数是最有用的。

添加新的 todo 时更新 todos 列表

TypeScript
1const queryClient = useQueryClient();2 3useMutation({4  mutationFn: updateTodo,5  // 当 mutate 调用时6  onMutate: async (newTodo) => {7    // 撤销相关的查询(这样它们就不会覆盖我们的乐观更新)8    await queryClient.cancelQueries(["todos"]);9 10    // 保存前一次状态的快照11    const previousTodos = queryClient.getQueryData(["todos"]);12 13    // 执行"乐观"更新14    queryClient.setQueryData(["todos"], (old) => [...old, newTodo]);15 16    // 返回具有快照值的上下文对象17    return { previousTodos };18  },19  // 如果修改失败,则使用 onMutate 返回的上下文进行回滚20  onError: (err, newTodo, context) => {21    queryClient.setQueryData(["todos"], context.previousTodos);22  },23  // 总是在错误或成功之后重新获取:24  onSettled: () => {25    queryClient.invalidateQueries("todos");26  },27});

更新单个的 todo

TypeScript
1useMutation({2  mutationFn: updateTodo,3  // 当 mutate 调用时4  onMutate: async (newTodo) => {5    // 取消相关的获取数据逻辑(这样它们就不会覆盖我们的乐观更新)6    await queryClient.cancelQueries(["todos", newTodo.id]);7 8    // 保存前一次状态的快照9    const previousTodo = queryClient.getQueryData(["todos", newTodo.id]);10 11    // 执行乐观更新12    queryClient.setQueryData(["todos", newTodo.id], newTodo);13 14    // 返回具有快照值和修改值的上下文对象15    return { previousTodo, newTodo };16  },17  // 如果修改失败,则使用 onMutate 返回的上下文18  onError: (err, newTodo, context) => {19    queryClient.setQueryData(20      ["todos", context.newTodo.id],21      context.previousTodo,22    );23  },24  // 总是在错误或成功之后重新获取:25  onSettled: (newTodo) => {26    queryClient.invalidateQueries(["todos", newTodo.id]);27  },28});

如果你愿意,你也可以使用 onsettled 函数来代替 onError 和 onSuccess 做处理:

TypeScript
1useMutation({2  mutationFn: updateTodo,3  // ...4  onSettled: (newTodo, error, variables, context) => {5    if (error) {6      // do something7    }8  },9});

本页为 TanStack Query 文档(React 版)的非官方中文翻译,原文由上游团队维护,遵循 MIT 许可。 译文如有偏差,以英文原文为准。

本页译文取自社区中文版 react-query-web-i18n(MIT),非本站翻译,已停止更新,内容可能与当前 API 有出入。

译自上游 (未记录版本)