跳到正文

React 状态与渲染 ​

  • 状态:未准备
  • 适用方向:前端 / Go 全栈
  • 最近复习:待填写
  • 下次复习:待安排

一句话回答 ​

React 由状态和属性计算 UI;每次渲染读取一份状态快照,setter 请求后续更新,React 再把计算结果提交到 DOM,组件执行不等于 DOM 一定改变。

原理解释 ​

render 与 commit ​

render 调用组件计算 UI,commit 才应用必要的 DOM 变更。render 必须保持纯净,不能启动订阅、改外部变量或执行网络副作用。渲染工作可能被重做或放弃,不能用函数执行次数代表用户看到的更新次数。

为什么连续加三次只加一? ​

jsx
function Counter() {
  const [count, setCount] = useState(0)
  function addThree() {
    setCount(c => c + 1)
    setCount(c => c + 1)
    setCount(c => c + 1)
  }
  return <button onClick={addThree}>{count}</button>
}

上述函数式更新按队列逐项计算,最终加三。若改成三次 setCount(count + 1),同一事件回调里的 count 属于同一快照,因此排入相同替换值。setter 不修改当前闭包中的 count,“setState 是异步的”不足以完整解释这个行为。

key 的作用 ​

React 根据组件在树中的位置、类型和 key 等确定身份。稳定业务 ID 有助于列表重排时正确复用;数组下标作为 key 在插入、删除和排序时可能导致局部状态错配。key 只需在同级唯一,不作为普通 prop 传给组件;改变 key 可以主动重置子树状态。

场景与边界 ​

状态是对象时应创建新引用表达更新,不直接原地修改。批处理减少提交,但不是跨所有事件、所有边界无限合并;现代 root 与旧版行为存在差异。不要依赖某个未经验证的渲染次数。

项目中的应用 ​

从 SimulSpeak 字幕状态 练习解释“一句话被持续修订”为何需要稳定身份;这与 React key 的目标相关,但业务消息合并与 React 节点复用属于不同层面。

常见追问 ​

  • 父组件渲染,子组件一定改 DOM 吗? 不一定;默认可能重新执行子组件,提交时只更新必要 DOM。
  • 为什么不用随机 key? 每次都变会重建子树、丢失状态,也破坏复用。
  • StrictMode 为什么看到重复执行? 开发模式会额外检查纯度和清理,具体检查范围与挂载位置有关,不应通过移除检查来掩盖副作用。

参考资料 ​

理解机制,讲清取舍,用复盘检验掌握。