react批量更新、同步/异步更新场景

📅 2026/6/20 3:25:08
react批量更新、同步/异步更新场景
React 16 到 React 19 期间批量更新Batch Update机制发生了很大变化尤其是 React 18 引入了自动批量更新Automatic Batching。面试中经常会问React16、React17、React18、React19 的批量更新区别哪些场景是同步更新哪些是异步更新下面详细讲解。一、什么是批量更新先看代码const [count, setCount] useState(0); function handleClick() { setCount(count 1); setCount(count 1); setCount(count 1); }很多人以为0 - 1 1 - 2 2 - 3实际最终 1因为 React 会把多个 state 更新合并Batch Update减少render() render() render()变成render()提高性能。二、React16/17 批量更新机制React16 和 React17只有 React 控制的事件中才会批量更新例如function App() { const [count, setCount] useState(0); const click () { setCount(c c 1); setCount(c c 1); setCount(c c 1); }; return ( button onClick{click} {count} /button ); }React 会批量更新setCount setCount setCount ↓ render 一次更新流程点击按钮 ↓ 收集更新 ↓ 更新队列 ↓ 统一计算state ↓ render三、React16/17 哪些场景不是批量更新1 setTimeoutsetTimeout(() { setCount(c c 1); setCount(c c 1); });React16/17render render两次渲染。因为setTimeout 不是 React 管理的事件2 PromisePromise.resolve().then(() { setCount(c c 1); setCount(c c 1); });React16/17render render3 原生事件document.addEventListener( click, () { setCount(c c 1); setCount(c c 1); } );React16/17render renderReact16/17 总结场景是否批量更新React事件✅生命周期函数✅setTimeout❌Promise❌async/await❌原生事件❌四、React18/19 自动批量更新React18 最大变化Automatic Batching 自动批量更新只要使用createRoot()就开启。setTimeoutsetTimeout(() { setCount(c c 1); setCount(c c 1); });React18render 一次PromisePromise.resolve().then(() { setCount(c c 1); setCount(c c 1); });React18render 一次async awaitasync function test() { await fetch(); setCount(c c 1); setCount(c c 1); }React18render 一次原生事件document.addEventListener( click, () { setCount(c c 1); setCount(c c 1); } );React18render 一次React18/19 总结场景React16/17React18/19React事件✅✅Promise❌✅setTimeout❌✅async/await❌✅原生事件❌✅五、同步更新和异步更新很多面试官喜欢问React setState 是同步还是异步答案既不是单纯同步 也不是单纯异步React事件中const click () { setCount(1); console.log(count); }输出0因为state没有立即更新React先收集更新。过程setState ↓ 放入更新队列 ↓ 事件结束 ↓ render ↓ state更新所以表现得像异步六、真正同步更新 flushSyncReact18import { flushSync } from react-dom; flushSync(() { setCount(1); }); console.log(count);React立即更新。执行流程flushSync ↓ 立即render ↓ 立即commit ↓ state更新七、React Fiber中的更新优先级React16开始引入Fiber更新不再是同步递归而是可中断更新会进入Lane优先级队列。例如高优先级用户输入input /中优先级按钮点击onClick低优先级列表渲染startTransition()startTransition(() { setList(bigData); });八、React18 Concurrent模式React18const root createRoot( document.getElementById(root) );开启并发特性。低优先级更新startTransition(() { setList(data); });高优先级setInput(value);React会先响应输入 ↓ 再渲染大列表避免页面卡顿。九、面试标准答案React16/17React事件中会批量更新 setTimeout、Promise、 async/await、原生事件中不会批量更新。React18/19引入Automatic Batching React事件、Promise、 setTimeout、async/await、 原生事件都会自动批量更新。setState同步还是异步本质上是同步创建Update对象 异步执行render和commit。 因此表现为异步。强制同步更新flushSync(() { setState(...) });React18新特性自动批量更新Automatic Batching并发渲染Concurrent RenderingstartTransitionSuspense增强Lane优先级调度这套内容基本覆盖了 React 16 → React 19 关于批量更新、同步/异步更新、Fiber 调度和面试高频考点。