🚀React 更新界面全流程:从 setState 到 像素上屏

#金石焕新程

🚀《React 更新界面全流程:从 setState 到 像素上屏》

面试常被追问:

"React 更新界面到底经历了哪些阶段?"

本文用一张图 + 一段可运行代码,带你走通 React 18(含并发特性) 的完整刷新链路。


📊 总览:一次更新 6 步曲

阶段 发生位置 关键 API
① 触发更新 开发者代码 setState / dispatch
② 构造更新对象 React 内部 Update
③ 调度 & 优先级 Fiber Scheduler scheduleUpdateOnFiber
④ Render 阶段(可中断) Fiber beginWorkcompleteWork
⑤ Commit 阶段(同步) DOM commitWorkcommitMutationEffects
⑥ 浏览器绘制 浏览器 requestAnimationFrame → 像素上屏

① 触发更新:setState 不是立刻刷 DOM!

jsx 复制代码
function Counter() {
  const [count, setCount] = useState(0);

  // 触发更新
  const handleClick = () => setCount(c => c + 1);

  return <button onClick={handleClick}>{count}</button>;
}
  • setCount 只是把 更新任务 放进 Fiber 队列,不会立即渲染

② 构造更新对象(Fiber 视角)

js 复制代码
// React 内部伪代码
const update = {
  lane: SyncLane,      // 优先级
  action: c => c + 1,  // 更新函数
  next: null           // 链表结构
};
fiber.updateQueue = appendUpdate(fiber.updateQueue, update);

③ 调度 & 优先级(时间切片)

js 复制代码
// React 18 并发调度
scheduleUpdateOnFiber(rootFiber, lane);
  • 高优先级任务 (用户输入)插队 ,低优先级任务让步
  • 浏览器空闲时继续可中断渲染

④ Render 阶段:Fiber 可中断遍历

plaintext 复制代码
beginWork → completeWork
  • 可中断:长列表渲染可分段进行(避免白屏)。
  • 双缓冲:一边渲染 Fiber 树,一边复用旧树。

⑤ Commit 阶段:同步提交到 DOM

plaintext 复制代码
commitWork
  ├─ commitMutationEffects  // 插入 / 更新 / 删除 DOM
  ├─ commitLayoutEffects    // 调用 useLayoutEffect
  └─ commitPassiveEffects   // 调用 useEffect
  • 同步不可中断,确保 DOM 与 React 树一致。

⑥ 浏览器绘制:像素上屏

  • React 把 styletransform 交给浏览器。
  • 浏览器在下一帧 VSync 信号后完成绘制。

🧪 实战:打断渲染(Concurrent Feature)

jsx 复制代码
import { startTransition } from 'react';

function Search() {
  const [query, setQuery] = useState('');
  const [list, setList] = useState([]);

  const handleChange = (e) => {
    const q = e.target.value;
    setQuery(q);
    startTransition(() => {
      // 低优先级更新:长列表过滤
      setList(filterList(q));
    });
  };

  return (
    <>
      <input value={query} onChange={handleChange} />
      {list.map(item => <li key={item.id}>{item.name}</li>)}
    </>
  );
}
  • startTransition 把长列表过滤标记为低优先级 ,高优先级输入不卡顿

🔍 调试技巧:浏览器 Performance 面板

  1. 火焰图:查看 Render、Commit 耗时。
  2. React DevTools Profiler:识别重渲染组件。
  3. Paint Flashing:高亮重绘区域。

🏁 一句话总结

React 更新 = 调度优先级 + 可中断渲染 + 同步提交 DOM + 浏览器绘制

记住 6 步曲,面试问「React 怎么更新界面」直接答:

"从 setState 触发 → Fiber 调度 → Commit → 像素上屏!"

相关推荐
NiceCloud喜云6 小时前
Opus 4.8 的 Effort Control 怎么选:Low 到 Max 五档策略
android·java·大数据·前端·c++·python·spring
wordbaby7 小时前
React Native + RNOH:跨页面数据回传的最佳实践与避坑指南
前端·react native
丷丩7 小时前
MapLibre GL JS第22课:查看本地GeoJSON
前端·javascript·map·mapbox·maplibre gl js
jiayong237 小时前
面试中遇到不熟悉问题的应对策略深度解析
面试·职场和发展
Front思8 小时前
AI前端工程师需要具备能力+
前端·人工智能·ai
JAVA社区9 小时前
Java高级全套教程(十)—— SpringCloudAlibaba超详细实战详解
java·开发语言·spring cloud·面试·职场和发展
ZC跨境爬虫10 小时前
跟着 MDN 学CSS day_29:(掌握文本与字体样式的核心艺术)
前端·css·ui·html·tensorflow
李子琪。11 小时前
网络空间安全深度实战:CSRF 漏洞原理剖析与基于 Token 的纵深防御体系构建(全栈实验报告)
前端·安全·csrf
冰暮流星11 小时前
javascript之history对象介绍
前端·笔记
IT_陈寒11 小时前
Vite热更新失灵?你可能漏了这个配置
前端·人工智能·后端