React渲染流程
React渲染流程全链路分析:从createRoot到render
1. 初始化阶段 - createRoot
入口文件
export * as ReactDom from "../packages/react-dom/client.ts";
export{ Fragment, Component } from "../packages/react";
function MyFunctionComponent() {
return <div>MyFunctionComponent</div>;
}
class MyComponent extends Component {
render() {
return <div>MyComponent
<MyFunctionComponent />
<h2>123</h2>
</div>;
}
}
createRoot方法实现
export const createRoot = (container: Container): RootType => {
// 创建一个根节点
const root: FiberRoot = createFiberRoot(container);
return new ReactDomRoot(root);
};
FiberRoot创建过程
export function createFiberRoot(containerInfo: Container): FiberRoot {
const root: FiberRoot = new FiberRootNode(containerInfo);
const uninitializedFiber: Fiber = createFiber(HostRoot, null, null);
root.current = uninitializedFiber;
uninitializedFiber.stateNode = root;
return root;
}
核心流程:
- 用户调用
ReactDom.createRoot(document.getElementById("root4")!) - 创建
FiberRootNode实例,保存DOM容器信息 - 创建
HostRoot类型的Fiber节点作为根Fiber - 建立FiberRoot和RootFiber的相互引用关系
- 返回
ReactDomRoot实例,包含render方法
2. 渲染阶段 - render
render方法实现
render(children: ReactNodeList) {
updateContainer(children, this._internalRoot);
}
updateContainer实现
export function updateContainer(element: ReactNodeList, container: FiberRoot) {
const current = container.current!;
current.memoizedState = {element};
scheduleUpdateOnFiber(container, current);
}
调度更新
export function scheduleUpdateOnFiber(root: FiberRoot, current: Fiber) {
// 设置当前正在处理的FiberRoot(整个应用的根容器)
workInProgressRoot = root;
// 设置当前正在处理的Fiber节点(从current开始协调)
workInProgress = current;
// 启动调度流程(最终会触发performConcurrentWorkOnRoot)
ensureRootIsScheduled(root);
}
3. 协调阶段 - Reconciliation
执行根节点工作
export function performConcurrentWorkOnRoot(root: FiberRoot) {
// ! 阶段1:Render阶段(可中断的协调过程)
// 同步渲染Fiber树(在简化版中暂时使用同步模式)
renderRootSync(root);
console.log("Fiber树构建完成:", root);
// ! 阶段2:Commit阶段(不可中断的DOM更新)
// 获取已完成的workInProgress树(即current.alternate)
const finishedWork: Fiber = root.current?.alternate!;
// 将完成的Fiber树挂载到root.finishedWork
root.finishedWork = finishedWork;
// 执行commit流程(DOM更新、生命周期调用等)
commitRoot(root);
}
构建Fiber树
function renderRootSync(root: FiberRoot) {
// ! 1.render开始 - 保存当前执行上下文并设置RenderContext标志
const prevExecutionContext = executionContext;
executionContext |= RenderContext;
// !2. 初始化 - 准备新的工作栈,创建workInProgress树
prepareFreshStack(root);
// !3. 遍历构建Fiber树 - 同步模式下循环处理所有工作单元
workLoopSync();
// !4. render结束 - 恢复之前的执行上下文状态
executionContext = prevExecutionContext; // 恢复之前的值
workInProgressRoot = null; // 整个流程结束,重置workInProgressRoot
}
工作循环
function workLoopSync() {
while (workInProgress !== null) {
performUnitOfWork(workInProgress);
}
}
处理单个工作单元
function performUnitOfWork(unitWork: Fiber) {
// 获取当前Fiber对应的current树节点(即上次渲染的版本)
const current = unitWork.alternate;
// ! 阶段1:beginWork处理
let next = beginWork(current, unitWork);
// 根据beginWork结果决定后续流程
if (next === null) {
// ! 情况1:没有产生新的工作单元(到达叶子节点)
completeUnitOfWork(unitWork);
} else {
// ! 情况2:存在子节点需要处理
workInProgress = next;
}
}
4. 提交阶段 - Commit
提交根节点
function commitRoot(root: FiberRoot) {
// ! 1.commit 开始 - 保存当前执行上下文并设置CommitContext标志
const prevExecutionContext = executionContext;
executionContext |= CommitContext;
// ! 2. commit阶段 - mutation阶段更新DOM树
commitMutationEffects(root, root.finishedWork!);
// ! 3. commit结束 - 恢复之前的执行上下文状态
executionContext = prevExecutionContext; // 恢复之前的值
workInProgressRoot = null; // 整个流程结束,重置 workInProgressRoot
}
5. 完整调用链路
-
入口调用:
ReactDom.createRoot(document.getElementById("root4")!).render(<div><MyComponent /></div>); -
创建阶段:
createRoot→createFiberRoot→new FiberRootNode→createFiber(HostRoot)- 返回
ReactDomRoot实例
-
渲染阶段:
render→updateContainer→scheduleUpdateOnFiber→ensureRootIsScheduled- 调度执行
performConcurrentWorkOnRoot
-
协调阶段:
renderRootSync→prepareFreshStack→workLoopSync- 循环执行
performUnitOfWork→beginWork/completeWork - 处理组件:
MyComponent类组件调用render方法,MyFunctionComponent函数组件直接执行
-
提交阶段:
commitRoot→commitMutationEffects- DOM操作:创建、更新、删除DOM节点
- 内容渲染到浏览器
6. 关键数据结构
-
FiberRoot:整个应用的根节点,包含:
current: 指向当前Fiber树containerInfo: DOM容器finishedWork: 完成工作的Fiber树
-
Fiber:React元素对应的工作单元,包含:
tag: 组件类型(如ClassComponent、FunctionComponent)type: 元素类型stateNode: DOM节点或组件实例return/child/sibling: 父/子/兄弟Fiber节点memoizedState: 上次渲染的状态flags: 副作用标记
7. 渲染示例分析
以示例代码中的组件渲染为例:
ReactDom.createRoot(document.getElementById("root4")!).render(<div>
<MyComponent />
</div>);
- 创建FiberRoot和HostRoot Fiber
- 调用render方法,传入JSX
- 更新容器,调度更新
- 构建Fiber树:
- div → HostComponent
- MyComponent → ClassComponent → 调用render方法
- MyFunctionComponent → FunctionComponent → 直接执行函数
- 完成Fiber树构建
- 提交变更到DOM
- 浏览器渲染页面,显示组件内容
这就是React从createRoot到render完成内容渲染到浏览器的完整流程。