跳到主要内容

排队更新 state

批处理怎样影响一次事件中的更新?​

  • 批处理: React 通常等同一事件处理中的更新都提交后再更新 UI,减少中间状态和重复工作;
  • 交互边界: 不会把彼此独立的有意点击无条件合并,第一次点击禁用按钮后,下一次点击应看到更新结果;
  • 快照不变: 批处理期间读取的变量仍属于当前渲染,原因见 state 快照笔记;

更新函数怎样累计待处理状态?​

  • 更新函数: setCount(n => n + 1) 描述从队列中前一个结果计算下一值,React 在处理队列时按顺序传入结果;
  • 连续调用: 三个加一更新函数把 0 依次变为 1、2、3,不依赖当前闭包中的 count;
function incrementThreeTimes() {
setCount((n) => n + 1);
setCount((n) => n + 1);
setCount((n) => n + 1);
}

直接替换与更新函数混用时怎样计算?​

  • 直接值: 在队列中表达“替换为这个值”,不依赖前一项的计算结果;
  • 顺序规则: 替换和更新都按入队顺序执行,后面的替换可以覆盖前面的累计结果;
队列项输入输出
替换为 505
n => n + 156
替换为 42642
setCount(5);
setCount((n) => n + 1);
setCount(42);

更新函数中为什么不能执行副作用?​

  • 纯计算: 更新函数在渲染过程中参与计算,只返回下一状态,不在里面发请求、触发其他状态更新或修改旧对象;
  • 开发检查: StrictMode 可能调用更新函数两次并忽略一次结果,纯函数才能使这种检查不改变业务结果;
  • 参数命名: 用 prevCount 或清晰的短名表示待处理状态,避免把它误认为永远等于当前闭包中的变量;