并发渲染核心本质:可中断的渲染任务
传统同步渲染(React 17 及更早)是一次性阻塞主线程的递归过程:从根组件到叶子组件一次性完成调和、提交,中途无法暂停,长列表、复杂组件渲染会造成页面卡顿、输入延迟。
并发渲染的核心是时间分片调度,React 将一次完整渲染拆分为多个微型任务单元(Fiber 节点),借助浏览器 requestIdleCallback / requestAnimationFrame 分割主线程时间片:
- 渲染任务可随时中断高优先级交互(点击、输入)到来时,暂停当前组件渲染,优先执行交互更新;
- 渲染任务可恢复主线程空闲后,从中断的 Fiber 节点继续完成剩余渲染逻辑;
- 双缓冲提交机制调和阶段完全在内存中完成,全部 Fiber 节点计算完毕后,一次性批量更新 DOM,避免频繁回流重绘。
React 19 取消同步根节点 API,所有应用默认启用并发调度,createRoot 成为唯一根渲染入口,不存在关闭并发渲染的开关,整套组件生命周期、Hooks 执行顺序全部基于并发模型重构。
并发架构下传统数据流方案的致命缺陷
在 use() 出现前,开发者依靠 useState + useEffect 处理异步数据,这套方案与并发渲染存在底层冲突,四大核心痛点无法根治:
- 瀑布式请求(Waterfall Fetch)组件串行执行
useEffect,父组件请求完成渲染子组件,子组件再发起新请求,网络请求串行阻塞,页面加载耗时成倍增加。 - 竞态条件(Race Condition)快速切换参数时,旧请求晚于新请求返回,覆盖最新状态,出现数据错乱,开发者必须手动增加 AbortController、请求标识判断。
- 渲染与副作用完全割裂渲染阶段无法读取异步数据,必须等待组件挂载完成后再触发请求,加载状态、异常处理需要额外维护多份 state 变量。
- 并发中断带来状态不一致风险并发渲染中断重启时,
useEffect执行时机不可控,容易出现重复请求、重复订阅,需要大量清理逻辑兜底。
传统 Hooks 将「渲染」和「异步数据获取」拆分为两个独立阶段,渲染是同步流程,数据请求是后置副作用,二者无法统一调度,并发场景下矛盾被无限放大。use() Hook 的诞生,正是为了在渲染原生流程内处理异步,统一数据流与渲染调度。