React setState同步异步机制与事务机制
说明React中setState何时同步更新何时异步更新,解释React的Transaction(事务)机制对setState行为的影响,以及React 18中的自动批处理(Automatic Batching)如何改变这一行为。
回答
苦行僧
传统React(17及之前)
异步场景(在React管控的事件处理函数中):
handleClick() {
setState({count: 1}); // 不立即更新
setState({count: 2}); // 合并
console.log(this.state.count); // 旧值
}
React将这些setState放入队列,在事务结束时批量合并更新。
同步场景(在setTimeout、Promise、原生事件中):
setTimeout(() => {
setState({count: 1}); // 立即执行
console.log(this.state.count); // 新值
}, 0);
因为不在React事务上下文中,每次setState立即触发重新渲染。
事务(Transaction)机制: React使用Transaction包装事件处理函数:
- 初始化事务(initialize)→ 打开isBatchingUpdates
- 执行事件处理(所有setState入队不更新)
- 关闭事务(close)→ 执行批量更新
React 18自动批处理(Automatic Batching):
- 所有场景(包括setTimeout、Promise、回调)默认批处理
- 使用
flushSync()可强制退出批处理进行同步更新 - 减少不必要的渲染次数,显著优化性能
// React 18中
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
// 只渲染一次
}, 0);