React Query 乐观更新

date
Nov 5, 2025
slug
react-query-optimistic-update
status
Published
tags
React Query
summary
让你的应用"先斩后奏"的艺术
type
Post
小伙伴们好!今天咱们聊聊一个让用户觉得你的应用"快如闪电"的黑科技——乐观更新!

开场:等待的痛苦

还记得上次你点击"点赞"按钮,然后等了1秒才看到效果吗?
这就像在餐厅点菜:
  • 传统方式:点菜 → 等厨师确认 → 才在菜单上打勾
  • 乐观更新:点菜 → 立即打勾 → 厨师说没货再划掉

问题演示:卡顿的复选框

看看这个待办事项应用,每次点击复选框都要等服务器响应:
用户体验:点击 → 等待... → 变化
这感觉就像:
  • 按电灯开关,灯要思考1秒才亮
  • 按电梯按钮,按钮要请示总部才亮起
太!难!受!了!

初级方案:基于状态的乐观更新

最简单的想法:突变进行中时,显示相反的状态!
工作原理:
  • 用户点击 → isPending = true → 立即显示相反状态
  • 请求成功 → 更新缓存 → UI保持不变(已经是对的)
  • 请求失败 → isPending = false → 自动恢复原状态

但是...有个大问题!

连续点击多个复选框时:
这就像多米诺骨牌,第一个倒下时把其他的也带倒了!

高级方案:直接更新缓存

既然问题是缓存和UI不同步,那就直接更新缓存!

步骤1:onMutate - 先下手为强

这就像:先在账本上记账,然后再去银行确认。

步骤2:准备回滚 - 留个后路

万一失败了怎么办?我们需要"后悔药"!

步骤3:onError - 吃后悔药

这就像玩游戏:
  1. 存档(快照)
  1. 尝试打Boss(乐观更新)
  1. 失败了?读档重来(回滚)

完整的防弹方案

执行流程图解

成功流程

失败流程

为什么要 cancelQueries?

想象这个场景:
cancelQueries 就是说:"停!用户在操作,其他请求都让路!"

封装:懒人福音

乐观更新代码太多?封装一下!

什么时候用乐观更新?

适合场景 ✅

  • 点赞/取消点赞
  • 勾选复选框
  • 切换开关
  • 拖拽排序
  • 简单的表单编辑
共同点:操作结果可预测

不适合场景 ❌

  • 支付操作(必须等确认)
  • 删除操作(可能需要二次确认)
  • 复杂计算(结果不可预测)
  • 权限相关(可能被拒绝)

最佳实践总结

  1. 简单场景用状态:单个UI元素,用 isPending 控制
  1. 复杂场景更新缓存:多个元素或需要数据一致性
  1. 永远准备回滚:乐观不代表盲目乐观
  1. 最后都要同步onSettled 是你的最后防线
  1. 取消竞争请求:避免数据竞争
记住:乐观更新就像"先斩后奏"——大部分时候没问题,但要准备好道歉(回滚)的方案!
好的用户体验 = 快速响应 + 数据准确。乐观更新让你两者兼得!


© 拾光 2025 - 2026

粤ICP备2025472574号