第二章:状态快照、更新队列与结构
第一章已经会“调用 setter”。本章回答更难的问题:为什么调用后当前变量没有立刻改变、为什么原地修改对象会破坏推理,以及为什么相同 JSX 位置有时保留状态、有时必须用 key 重置。
具体前置
- 能写受控文本框并从事件读取
event.target.value; - 能用稳定业务 id 渲染、删除和重排列表;
- 理解对象与数组变量保存的是引用;知道展开语法只做一层浅复制。
每个示例仍是 React 19 + Vite 的完整 src/App.jsx,不使用 Immer 或任何第三方库。
依赖顺序
- 快照、队列与批处理:先固定“当前渲染看到什么”,再逐项计算更新队列。
- 对象与数组的不可变更新:setter 排队的是下一份值;复合值必须以新引用表达变化。
- 状态结构、保留与重置:最后决定哪些值值得存,以及状态应跟哪个组件身份一起活着。
可观察成果
- 同一个点击处理器里三次
setCount(count + 1)只得到+1,三次更新函数得到+3,并能逐项写出队列计算; - 编辑任务的嵌套负责人时,旧任务数组、旧任务对象都保持不变,未编辑项继续复用原引用;
- 切换同一位置的联系人时,能选择保留草稿或用联系人 id 作为 key 明确重置,而不是靠偶然的 JSX 写法。
完成后再看第二章练习答案。