使用 React Query 和 Zustand 的乐观模式
使用 React Query 的 onMutate/onError/onSettled 回调和 Zustand,构建结构化的乐观界面流程
使用 React Query 和 Zustand 的乐观模式 是 CoddyKit 上的免费 React Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。
React Query 的 useMutation 概览
React Query 的 useMutation 钩子通过三个生命周期回调,为乐观更新提供内置基础设施:onMutate(在变更前触发,返回一个上下文对象)、onError(失败时触发,接收该上下文)和 onSettled(成功或失败时都会触发)。这种结构专门用于乐观更新模式。
onMutate:乐观更新阶段
在 onMutate 中,您需要执行三个步骤:首先,取消受影响数据的所有进行中查询(await queryClient.cancelQueries({ queryKey }));然后,保存当前缓存的快照(queryClient.getQueryData(queryKey));最后,将乐观更新应用到缓存(queryClient.setQueryData(queryKey, updater))。将该快照作为上下文返回。
onError:使用上下文回滚
onError 回调会接收错误、变更变量以及 onMutate 返回的上下文。请使用该上下文进行回滚:queryClient.setQueryData(queryKey, context.previousData)。上下文连接了 onMutate 中获取的快照与 onError 中执行的回滚。
onSettled:重新获取以同步状态
onSettled 回调无论成功还是失败都会触发。请使用它重新获取查询并与服务器状态同步:queryClient.invalidateQueries({ queryKey })。这样在任何变更之后——无论变更成功(服务器可能转换了数据)还是失败(回滚已完成)——您最终都会与服务器的真实状态保持一致。
React Query 乐观切换待办事项
一个实际例子是切换待办事项的完成状态。在 onMutate 中,先保存待办事项列表的快照,然后更新缓存中的特定待办事项。在 onError 中,从上下文恢复快照。在 onSettled 中,使待办事项查询失效以便重新获取。用户会立即看到切换结果;服务器则在后台同步。
Zustand 乐观更新
在 Zustand 存储中,乐观更新很直接:创建一个操作 updateItem(id, changes),立即更新存储中的项目,然后调用接口。如果接口失败,再调用另一个操作 revertItem(id, previousState)。Zustand 的同步状态更新会让乐观步骤立即生效。
使用 Immer 和 Zustand 处理复杂更新
乐观更新深层嵌套的 Zustand 状态时,请使用 Immer 的 produce 来简洁地执行变更:set(produce(state => { state.items[id] = { ...state.items[id], ...changes } }))。Immer 使用可变语法处理不可变更新,使复杂的嵌套状态变更更易读且更安全。
React 19 的 useOptimistic 钩子
React 19 引入了 useOptimistic(state, updateFn),这是一个用于服务端操作中乐观更新的内置钩子。const [optimisticState, addOptimistic] = useOptimistic(items, (state, newItem) => [...state, newItem])。调用 addOptimistic(newItem) 会立即更新用户界面,同时服务端操作在异步运行。
useOptimistic 自动回滚
useOptimistic 会自动处理回滚。当服务端操作完成时(无论成功还是出错),React 都会还原乐观状态,并应用服务器返回的真实状态。您不需要编写手动回滚逻辑——React 会在该操作的 Suspense 边界期间管理乐观更新的生命周期。
三种方案的比较
手动乐观更新提供完整控制,但需要编写样板代码。React Query 的 onMutate/onError/onSettled 会与查询缓存集成,以实现自动同步。useOptimistic 是服务端操作中最简单的方案,但要求 React 19 和服务端操作架构。请根据您的数据层选择方案:简单本地状态使用手动模式,REST 接口使用 React Query,RSC/服务端操作使用 useOptimistic。
选择合适的模式
选择乐观更新模式时,请考虑您的架构。如果您在整个应用中使用 React Query,其 onMutate 模式保持一致并了解缓存。如果您使用 Zustand 管理全局状态,基于操作的模式会自然适用。如果您使用 React 19 和服务端操作,useOptimistic 是符合惯例的选择。在同一个应用中混用这些模式很常见,也完全可以接受。
React Query 中 onMutate 的返回值
在 React Query 中,为了让 onError 能够执行回滚,onMutate 回调应返回什么?
课程回顾:乐观更新模式
React Query 的 useMutation 使用 onMutate(取消查询、创建快照、应用乐观更新并返回上下文)、onError(从上下文恢复快照)和 onSettled(使查询失效以便重新获取)。Zustand 的乐观更新会立即调用状态操作,然后调用接口,并在失败时回滚。React 19 的 useOptimistic 能在服务端操作中自动回滚。请选择适合您的数据层架构的模式。
常见问题解答
「使用 React Query 和 Zustand 的乐观模式」课时是免费的吗?
是的 — 「使用 React Query 和 Zustand 的乐观模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。
「使用 React Query 和 Zustand 的乐观模式」这节课中我会学到什么?
使用 React Query 的 onMutate/onError/onSettled 回调和 Zustand,构建结构化的乐观界面流程 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 React Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「使用 React Query 和 Zustand 的乐观模式」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 React Academy 课中编写并运行代码吗?
能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 什么是乐观界面,以及何时使用
- 手动实现乐观更新
- 错误回滚与冲突解决
- 使用 React Query 和 Zustand 的乐观模式