文章目录
前言
可视化地讲解 React 元素(Virtual DOM)的生命周期,包括:
- React Element 是什么
- 从 JSX 到真实 DOM 的全过程
- 涉及的生命周期钩子
- 组件挂载 / 更新 / 卸载的流程图
🧱 一、React Element 是什么?
React Element 是 JSX 表达式转换后的结果,它只是一个用于描述 UI 的普通 JS 对象。
// JSX
<h1 className="title">Hello</h1>
// 被编译为:
React.createElement('h1', { className: 'title' }, 'Hello')
// 返回:
{
$$typeof: Symbol(react.element),
type: 'h1',
props: {
className: 'title',
children: 'Hello'
}
}
它不是 HTML 也不是 DOM,而是虚拟 DOM,用于告诉 React:我要渲染什么内容。
🧠 二、React 元素生命周期总览图
[JSX] --> [React.createElement()] --> [Virtual DOM Tree]
|
[Reconciliation (Diff)]
|
[Fiber 架构调度 + commit 阶段]
|
[真实 DOM 创建/更新]
↓
[组件生命周期钩子触发]
🚦 三、生命周期阶段详解(函数组件为例)
阶段 | 发生什么 | 涉及内容 |
---|---|---|
① 创建阶段 | JSX 被转为 React Element 对象 | React.createElement |
② 构建虚拟 DOM | 所有 Element 被组成树结构 | Fiber Tree |
③ 调和阶段 | 与上次的 Fiber 比对差异 | reconciliation |
④ 提交阶段 | 更新真实 DOM + 触发生命周期钩子 | useEffect 、DOM API |
⑤ 更新阶段 | 状态变化 → 触发新 Element → 重走 Diff 流程 | useEffect , useMemo |
⑥ 卸载阶段 | DOM 被移除 → 清理副作用 | useEffect cleanup |
🧩 四、可视化:函数组件挂载过程(简化流程图)
App()
↓
JSX: <h1>Hello</h1> 返回
↓
React.createElement → React Element
↓
Fiber 构建(VNode 树)
↓
Diff:新 vs 旧(首次无旧 → 全部挂载)
↓
Commit:创建 DOM(document.createElement)
↓
插入页面(appendChild)
↓
useEffect(() => { ... }, []) 触发
🔁 五、更新过程(例如:点击按钮改变文本)
setState() 触发
↓
新 JSX 生成新 Element
↓
新 Fiber Tree 与旧 Fiber Tree Diff
↓
找出差异(如文本变化)
↓
只更新需要变更的 DOM(如 innerText)
↓
commit 阶段完成
↓
useEffect() 执行更新后的副作用
❌ 六、卸载过程(如条件渲染中被隐藏的组件)
Component 被从 JSX 移除
↓
React Diff 检测到组件已不存在
↓
Fiber 标记为 `deletion`
↓
DOM 元素从页面中删除
↓
useEffect cleanup 执行
🧪 补充:Fiber 中如何处理 Element?
- 每个 React Element 会被包装为 Fiber 节点(FiberNode)
- Fiber Tree 是一棵链式结构树(child → sibling → return)
- 在
render
和commit
两阶段分别处理计算 & DOM 更新
✅ 总结一句话
React Element 是 UI 的描述符,它的生命周期跨越了虚拟 DOM 构建、Fiber 调度、DOM 渲染与副作用清理,每一次 setState 其实都在触发一次“React Element → DOM” 的完整生命周期流。