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

乐观更新 optimistic-updates

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

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

添加新的 todo 时更新 todos 列表

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

更新单个的 todo

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

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

JavaScript
1useMutation(updateTodo, {2  // ...3  onSettled: (newTodo, error, variables, context) => {4    if (error) {5      // do something6    }7  },8});

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

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

译自上游 (未记录版本)