React中createRoot函数原理解读——Element对象与Fiber对象、FiberRootNode与HostRootNode
【2024最新版】React18 核心源码分析教程(全61集)
Element对象与Fiber对象
在 React 中,Element 对象 和 Fiber 对象 是核心概念,用于实现 React 的高效渲染和更新机制。以下是它们的详细解读:
1. Element 对象
定义
React 的 Element 对象 是通过 React.createElement
或 JSX 创建的**描述 UI 的普通 JavaScript 对象
**。
结构
一个典型的 React Element 对象的结构如下:
const element = {type: 'div', // 或者是组件函数/类,表示元素类型props: {children: [/* 子元素 */],className: 'example',},key: null, // 用于唯一标识(diff 算法优化)ref: null, // 用于获取组件实例或 DOM$$typeof: Symbol(react.element), // 用于区分是否是 React 元素
};
特点
- 不可变:React Element 是不可变的,描述的是 UI 的快照。
- 轻量:它是
UI 的描述,并不包含状态或方法
。 - 静态描述:只表示渲染内容的静态信息,
真正的 DOM 操作由 Fiber 对象实现
。
2. Fiber 对象
定义
Fiber 对象 是 React 16+ 引入的内部数据结构,用于管理组件的更新和渲染工作
。
结构
一个 Fiber 对象的基本结构如下:
const fiber = {tag: 5, // 表示 Fiber 类型,比如函数组件、类组件、HostComponent(如 div)type: 'div', // 与 Element 的 type 对应key: null, // 用于唯一标识stateNode: DOM节点或类组件实例, // 当前 Fiber 的实际实例,DOM 节点或类组件实例child: Fiber, // 第一个子节点sibling: Fiber, // 下一个兄弟节点return: Fiber, // 父节点pendingProps: {}, // 本次更新的新 propsmemoizedProps: {}, // 上一次渲染的 propsmemoizedState: {}, // 上一次渲染的 stateeffectTag: 0, // 副作用标志,表示需要执行的操作类型nextEffect: null, // 下一个有副作用需要处理的 FiberupdateQueue: {}, // 存放 state 更新队列
};
特点
- 动态:Fiber 是 React 的工作单元,包含组件的状态、更新等动态信息。
- 链表结构:
Fiber 对象构成了一棵 Fiber 树
。- 每个 Fiber 节点通过
child
、sibling
和return
连接。
- 与 Element 不同的职责:
- Element 是静态描述,Fiber 负责调度和计算实际的 UI 变化。
- Fiber 引入了时间切片机制,
支持任务中断和优先级调度
。
- 双缓存机制:
- React 使用两棵 Fiber 树(
current
和workInProgress
)来实现双缓存
,减少不必要的 DOM 操作。
- React 使用两棵 Fiber 树(
3. Element 和 Fiber 的关系
特性 | Element 对象 | Fiber 对象 |
---|---|---|
职责 | 描述 UI | 管理组件状态、更新任务和渲染 |
生成 | 由 React.createElement 创建 | 由 React 调度和渲染过程 生成 |
结构 | 轻量、不可变的 JS 对象 | 复杂、包含状态和关系的动态对象 |
生命周期 | 创建后一直存在,描述 UI 快照 | 每次渲染会重新生成或复用 |
关系 | 是 Fiber 的静态输入 | 是 Element 的动态实现 |
4. Fiber 的核心功能
调度更新任务
:通过优先级控制任务的执行,允许任务中断。状态管理
:保存组件的状态和属性,管理setState
。DOM 更新
:对比新旧 Fiber 树,生成最小更新路径(Diff 算法)。副作用管理
:通过effectTag
管理 DOM 操作、生命周期回调等。
5. 总结
- React Element 是 UI 的静态描述,简单且不可变。
- Fiber 是 React 内部的工作单元,负责处理状态、调度更新和渲染。
Fiber 的引入是 React 性能优化的关键,尤其是在构建复杂的 UI 和实现时间切片时。Element 和 Fiber 分工明确,共同构建了 React 的高效渲染机制。
FiberRootNode与HostRootFiber
在 React 的内部实现中,HostRootFiber
和 FiberRootNode
是 React 核心中的两个重要概念,分别与 Fiber 树的根节点和渲染树的管理密切相关。以下是对这两个概念的详细解析。
1. FiberRootNode
定义
FiberRootNode
是 React 的根容器节点,用于管理整个应用的 Fiber 树和渲染环境
。- 它是 React 应用的真正入口点,通常与宿主环境(如
DOM
或React Native
)的根容器绑定
。
作用
- 管理宿主环境的渲染目标:
- 保存与宿主环境相关的信息(如 DOM 容器)。
- 对应浏览器中的根节点(如
document.getElementById('root')
)。
- 控制 Fiber 树的生命周期:
- 通过
current
字段管理当前正在渲染的 Fiber 树。 - 配合
双缓存机制
,切换current
和workInProgress
。
- 通过
存储调度信息
:- 保存任务的优先级(如时间切片相关)。
- 存储更新队列和渲染进度。
结构
FiberRootNode
的典型结构如下:
const fiberRootNode = {containerInfo: DOMContainer, // 宿主环境的根容器,如 DOM 节点current: HostRootFiber, // 当前的根 FiberfinishedWork: null, // 已完成的 Fiber 树pendingLanes: 0, // 表示待处理更新的优先级队列eventTimes: [], // 记录事件触发时间,用于调度优化callbackNode: null, // 当前调度的回调函数callbackPriority: NoPriority, // 当前调度的优先级
};
2. HostRootFiber
定义
HostRootFiber
是 React 应用的Fiber 树的根节点
。- 它对应于 React 渲染树的入口点,表示整个应用的根。
作用
- 承载应用的 Fiber 树:整个应用的组件树从
HostRootFiber
开始构建,作为 Fiber 树的根节点。 - 关联 Fiber 树与渲染器:它是连接 Fiber 树与 DOM(或其他宿主环境,如 React Native)之间的桥梁。
- 管理应用状态:
HostRootFiber
保存整个应用的状态(如pendingProps
和memoizedState
)。updateQueue
中记录了根节点的更新任务队列。
结构
HostRootFiber
是一个特殊的 Fiber 节点,具有以下字段:
const hostRootFiber = {tag: HostRoot, // Fiber 类型标记,表示是 HostRootstateNode: FiberRootNode, // 指向 FiberRootNode 实例child: Fiber, // 子节点,指向应用的第一个组件(如 <App />)pendingProps: {}, // 本次更新传入的 propsmemoizedProps: {}, // 已保存的 propsmemoizedState: {}, // 当前组件状态updateQueue: {}, // 存储更新任务的队列alternate: WorkInProgressFiber, // 指向 workInProgress Fiber,用于双缓存机制
};
3.FiberRootNode 与 HostRootFiber 的关系
特性 | HostRootFiber | FiberRootNode |
---|---|---|
定义 | Fiber 树的根节点,代表 React 树的逻辑入口 | React 根容器,管理 Fiber 树与宿主环境 |
存储内容 | 应用的根组件和状态(App 的入口) | 宿主环境信息(如 DOM 容器)和调度状态 |
连接关系 | 通过 stateNode 引用 FiberRootNode | 通过 current 引用 HostRootFiber |
用途 | 描述 Fiber 树的根 | 管理整个应用的渲染和更新机制 |
生命周期 | 每次更新会创建新的 workInProgress 副本 | 始终存在,贯穿应用生命周期 |
4. 运行机制中的作用
-
初始化时:
- React 创建
FiberRootNode
并将HostRootFiber
挂载到FiberRootNode
的current
属性上。 containerInfo
保存宿主环境的信息。
- React 创建
-
更新时:
- 更新会从
HostRootFiber
开始,React 使用双缓存机制
创建workInProgress
树。 - 在
调和
过程中,React 通过FiberRootNode
调度任务,确保高优先级任务优先完成
。
- 更新会从
-
渲染完成:
- 当 Fiber 树完成渲染(即
finishedWork
不为null
),React 将FiberRootNode.current
切换
到新的 Fiber 树。
- 当 Fiber 树完成渲染(即
5. 总结
FiberRootNode
是管理上的根节点,负责协调 Fiber 树和宿主环境之间的关系。HostRootFiber
是逻辑上的根节点,描述了 React 树的结构。
它们的协作是 React 内部运行机制的核心,支撑了高效的渲染与更新流程。
相关文章:

React中createRoot函数原理解读——Element对象与Fiber对象、FiberRootNode与HostRootNode
【2024最新版】React18 核心源码分析教程(全61集) Element对象与Fiber对象 在 React 中,Element 对象 和 Fiber 对象 是核心概念,用于实现 React 的高效渲染和更新机制。以下是它们的详细解读: 1. Element 对象 定…...

利用Python实现Union-Find算法
Union-Find(又称 并查集)是一种高效解决 动态连通性问题 的算法。它主要提供两种操作: Union(x, y):将元素 x 和 y 连接。Find(x):找到元素 x 所属的集合的标识符(通常是集合的根节点)。 常用…...

【LeetCode: 912. 排序数组 + 归并排序】
🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…...
AI时代来了,我们不再需要IDE了
大家好,我是编程乐趣。 最近在思考一个问题,那就是AI这么强大。 未来有没有可能,我们就不需要不需要开发工具了,只需一个浏览器就可以开发软件了。 一、AI带来的变化 1、代码生成与补全 AI工具如GitHub Copilot等能够根据代码…...
PL/SQL语言的网络编程
PL/SQL语言的网络编程 引言 在信息化迅速发展的今天,网络编程作为现代软件开发的重要组成部分,受到了广泛关注。而在数据库管理系统中,Oracle 提供了 PL/SQL(Procedural Language/Structured Query Language)&#x…...
vue video重复视频 设置 srcObject 视频流不占用资源 减少资源浪费
// 直接设置srcObject减少获取视频流:通过 captureStream() 方法从下方视频元素获取视频流。 // 设置 srcObject:将获取到的视频流设置为上方视频的 srcObject 减少资源浪费 // 获取到需要复制到的dom元素 const firstVideoElement proxy.$refs.firs…...

JavaFx 21 项目Markdown 预览、编辑、新建、文件树、删除、重命名
项目文件结构 项目的源代码和资源文件存放在以下路径: 源代码: src/main/java/com/kong/markdown/ 包含多个 Java 文件,主要实现了应用的功能: App.java:主类,可能包含应用的启动逻辑。FileService.java:可能与文件操作相关的服务类。MainController.java:控制器类,可…...

git项目提交步骤(简洁版)
1.创建仓库 2.填写 信息 3.点击这个按钮 4.找到要上传的文件,在目录内右键点击 5.依次执行命令 在命令窗口中输入:git init 复制仓库地址: 在命令窗口中输入:git remote add origin 仓库地址 在命令窗口中输入:…...

风水算命系统架构与功能分析
系统架构 服务端:Java(最低JDK1.8,支持JDK11以及JDK17)数据库:MySQL数据库(标配5.7版本,支持MySQL8)ORM框架:Mybatis(集成通用tk-mapper,支持myb…...
Clojure语言的学习路线
Clojure语言的学习路线 Clojure是一种现代的Lisp方言,运行于Java虚拟机(JVM)上。它具备强大的函数式编程特性,支持并发和多线程编程,适合处理复杂的数据和计算任务。由于其简洁和灵活的语法,Clojure在数据…...

网络安全核心目标CIA
网络安全的核心目标是为关键资产提供机密性(Confidentiality)、可用性(Availablity)、完整性(Integrity)。作为安全基础架构中的主要的安全目标和宗旨,机密性、可用性、完整性频频出现,被简称为CIA,也被成为你AIC,只是顺序不同而已…...

Wi-Fi Direct (P2P)原理及功能介绍
目录 Wi-Fi Direct (P2P)介绍Wi-Fi Direct P2P 概述P2P-GO(P2P Group Owner)工作流程 wifi-Direct使用windows11 wifi-directOpenwrtwifi的concurrent mode Linux环境下的配置工具必联wifi芯片P2P支持REF Wi-Fi Direct ÿ…...
Perl语言的数据结构
Perl语言的数据结构 Perl是一种功能强大的、灵活的脚本语言,广泛用于文本处理、系统管理、网络编程以及许多其他领域。其灵活性不仅体现在语法上,还体现在其丰富的数据结构上。本文将深入探讨Perl的主要数据结构,包括标量、数组、哈希以及引…...

【MFC】设置CTreeCtrl单个节点的文字颜色
问题 功能调整需要依据不同状态设置树控件中单个节点的文字颜色。 分析 1、CTreeCtrl本身有设置文字颜色的接口SetTextColor,但是这个接口是设置树控件整体的文字颜色。 2、在自定义接口可以对树控件单个节点进行更新文字颜色和背景颜色,接收自定义绘制…...
【CSS】设置滚动条样式
文章目录 基本语法用法案例 基本语法 在CSS中,可以使用 ::-webkit-scrollbar 和相关伪元素来为滚动条设置样式,但请注意这些伪元素是非标准的,主要用于WebKit内核浏览器(如Chrome、Safari)。 ::-webkit-scrollbar CSS …...

Gitlab-Runner配置
原理 Gitlab-Runner是一个非常强大的CI/CD工具。它可以帮助我们自动化执行各种任务,如构建、测试和部署等。Gitlab-Runner和Gitlab通过API通信,接收作业并提交到执行队列,Gitlab-Runner从队列中获取作业,并允许在不同环境下进行作…...
代码随想录 哈希 test 8
18. 四数之和 - 力扣(LeetCode) 与三数之和类似,重点在剪枝和去重的区别,由于target可正可负,因此需要分两种情况讨论,如果target为正,则若当前选择的元素之和大于target,需要跳出这…...

[SAP ABAP] 使用LOOP AT...ASSIGNING FIELD-SYMBOL 直接更新内表数据
使用 LOOP AT...ASSIGNING FIELD-SYMBOL... 可以直接修改内表中的数据,而不需要先将内表数据复制到相应的工作区,然后再更新回内表中,从而提高性能 针对上述代码进行优化,我们使用LOOP AT...ASSIGNING FIELD-SYMBOL 直接更新内表数…...
MySQL数据导出导入
一、数据导出 1.导出全库备份到本地的目录 mysqldump -u$USER -p$PASSWD -h127.0.0.1 -P3306 --routines--default-character-setutf8 --lock-all-tables --add-drop-database -A >db.all.sql 2.导出指定库到本地的目录(例如mysql库) mysqldump -u$USER -p$PASSWD -h127.…...
leetcode 127. 单词接龙
题目:127. 单词接龙 - 力扣(LeetCode) 先建立一颗trie树,从beginWord开始bfs;bfs的过程中,对trie树进行dfs寻找“只差一个字母”的其他未遍历到的字符串;直到bfs遍历到endWord。 struct Node …...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...