这个问题要区分 React 版本和调用场景。结论是:在 React 18 及之后,setState 在所有场景下都是批处理(异步更新)的,包括事件处理、Promise、setTimeout、原生事件;在 React 17 及之前,只有 React 合成事件和生命周期内是批处理的,在原生事件、setTimeout、Promise 回调中是同步执行的。

原理:"异步"不是真正的异步代码,而是 React 会把多次 setState 合并,延迟到当前任务结束时统一触发一次渲染(批处理),所以调用 setState 后立即读 this.state / 变量拿到的是旧值。要依赖最新状态,可用函数式更新 setState(prev => prev + 1),或在 useEffect / 类组件的 componentDidUpdate 中读取。React 18 引入了 createRoot 和自动批处理,需要立即刷新时可用 flushSync 强制同步执行。

易错点:函数组件中 useState 的 setter 同样遵循批处理规则。追问方向:并发渲染下 setState 如何进入不同优先级车道、为什么批处理能提升性能、flushSync 的使用场景。