0Pricing
React Academy · 课时

使用 useMutation 执行变更

使用 useMutation 向 API 提交数据,处理加载和错误状态,并在成功后使查询失效。

使用 useMutation 执行变更 是 CoddyKit 上的免费 React Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。

欢迎

在本课中,您将使用 useMutation 向 API 发送数据,处理加载和错误状态,并在变更操作成功后使过期查询失效。

useMutation 基础

使用 mutationFn 调用 useMutation。它会返回 mutate 函数和状态属性。调用 mutate() 即可触发操作。
import { useMutation } from '@tanstack/react-query';

const { mutate, isLoading, isError } = useMutation({
  mutationFn: (newPost) => fetch('/api/posts', {
    method: 'POST',
    body: JSON.stringify(newPost),
  }).then(r => r.json()),
});

调用 mutate

在事件处理程序中调用 `mutate(variables)`。variables 会作为第一个参数传递给 mutationFn。
<button onClick={() => mutate({ title: 'New Post' })}>
  Create Post
</button>

回调:onSuccess、onError、onSettled

为 useMutation 添加回调选项:操作成功后运行 onSuccess,失败时运行 onError,两种情况都会运行 onSettled(类似 finally)。
useMutation({
  mutationFn: createPost,
  onSuccess: (data) => {
    console.log('Created:', data);
    navigate('/posts/' + data.id);
  },
  onError: (error) => {
    toast.error(error.message);
  },
})

变更操作后使查询失效

变更操作成功后,请使相关查询失效,以便 React Query 重新获取最新数据。在 onSuccess 中使用 queryClient.invalidateQueries。
import { useQueryClient } from '@tanstack/react-query';

const queryClient = useQueryClient();

const { mutate } = useMutation({
  mutationFn: createPost,
  onSuccess: () => {
    queryClient.invalidateQueries({ queryKey: ['posts'] });
  },
});

使用 mutateAsync 编写 await 语法

使用 `mutateAsync` 代替 `mutate`,即可等待变更操作完成,并通过 try/catch 处理结果。
const { mutateAsync } = useMutation({ mutationFn: createPost });

async function handleSubmit() {
  try {
    const post = await mutateAsync({ title: 'Draft' });
    navigate('/posts/' + post.id);
  } catch (err) {
    setError(err.message);
  }
}

变更操作期间禁用提交

使用 `isPending`(或 `isLoading`),在变更操作进行期间禁用提交按钮。
const { mutate, isPending } = useMutation({ mutationFn: saveItem });

<button onClick={() => mutate(item)} disabled={isPending}>
  {isPending ? 'Saving...' : 'Save'}
</button>

使用 onMutate 实现乐观更新

使用 onMutate 在服务器响应之前乐观地更新缓存。在 onError 中使用 onMutate 返回的上下文执行回滚。
useMutation({
  mutationFn: likePost,
  onMutate: async (id) => {
    await queryClient.cancelQueries({ queryKey: ['posts'] });
    const prev = queryClient.getQueryData(['posts']);
    queryClient.setQueryData(['posts'], old => old.map(p =>
      p.id === id ? { ...p, likes: p.likes + 1 } : p));
    return { prev };
  },
  onError: (err, id, ctx) => queryClient.setQueryData(['posts'], ctx.prev),
  onSettled: () => queryClient.invalidateQueries({ queryKey: ['posts'] }),
})

重置变更状态

调用 useMutation 返回的 `reset()`,清除变更状态(数据、错误和状态)。这在离开当前页面或清空表单后很有用。
const { mutate, isError, reset } = useMutation({ /* ... */ });

{isError && (
  <>
    <p>Error!</p>
    <button onClick={reset}>Try Again</button>
  </>
)}

并行执行多个变更操作

并行多次调用 mutate,每次调用都会被独立跟踪。使用 mutateAsync 配合 Promise.all 执行并行变更操作。
await Promise.all([
  mutateAsync({ id: 1, title: 'First' }),
  mutateAsync({ id: 2, title: 'Second' }),
]);

快速检查

变更操作成功后,确保界面显示最新数据的推荐方式是什么?

回顾

useMutation 提供 mutate、isPending 和生命周期回调。使用 onSuccess 使相关查询失效。使用 mutateAsync 编写基于 await 的流程。使用 onMutate/onError 实现带回滚功能的乐观更新。

接下来

下一课:**使用 useInfiniteQuery 实现无限滚动与分页**——您将获取分页数据,并无缝加载更多页面。

常见问题解答

「使用 useMutation 执行变更」课时是免费的吗?

是的 — 「使用 useMutation 执行变更」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。

「使用 useMutation 执行变更」这节课中我会学到什么?

使用 useMutation 向 API 提交数据,处理加载和错误状态,并在成功后使查询失效。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 React Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「使用 useMutation 执行变更」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 React Academy 课中编写并运行代码吗?

能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 设置 React Query 与 QueryClient
  2. 缓存、过期时间与后台重新获取
  3. 使用 useMutation 执行变更
  4. 使用 useInfiniteQuery 实现无限滚动与分页
← 返回 React Academy