使用 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 反馈 — 无需本地设置。
此课程中的所有课时
- 设置 React Query 与 QueryClient
- 缓存、过期时间与后台重新获取
- 使用 useMutation 执行变更
- 使用 useInfiniteQuery 实现无限滚动与分页