[FE] React 初窥门径(五):React 组件的加载过程(commit 阶段)
1. 回顾
前一篇文章我们看到,ReactDOM.render 总共包含这些步骤,
然后介绍了 performSyncWorkOnRoot 做的事情,它主要做了两件事,
-
renderRootSync可称之为 render 阶段:创建了一颗 Fiber Tree(包含 html fragment 并未挂在到 DOM 中) -
commitRoot可称之为 commit 阶段:将 Fiber Tree 实际写入 DOM
前文我们重点介绍了 render 阶段 的业务逻辑,这个阶段由 renderRootSync 来完成,
其中 markRenderStarted 和 markRenderStopped 标志了 render 阶段 的开始和结束。
[6] performSyncWorkOnRoot <- 已创建好了 一个 FiberRootNode 和 两个 FiberNode(下文解释)[7] renderRootSync[8] markRenderStarted <- 开始 render 阶段[8] workLoopSync <- 从上到下处理 FiberTree[9] performUnitOfWork ---- [HostRoot {tag: 3}] <- 处理 WIP FiberNode[10] beginWork$1[11] beginWork[12] updateHostRoot[13] reconcileChildren <- 创建 child FiberNode[9] performUnitOfWork ---- [IndeterminateComponent {tag: 2}] (<App />) <- 处理 child FiberNode[10] beginWork$1[11] beginWork[12] mountIndeterminateComponent[13] renderWithHooks[14] Component[13] reconcileChildren <- 创建 child FiberNode[9] performUnitOfWork ---- [HostText {tag: 6}] ('hello world') <- 处理 child FiberNode[10] beginWork$1[11] beginWork[12] updateHostText[10] completeUnitOfWork <- 从下到上处理 FiberTree[11] completeWork ---- [HostText {tag: 6}] ('hello world')[12] createTextInstance[13] createTextNode[14] createTextNode [HTMLElement] ('hello world')[11] completeWork ---- [IndeterminateComponent {tag: 2}] (<App />)[11] completeWork ---- [HostRoot {tag: 3}][8] markRenderStopped <- 结束 render 阶段[7] commitRoot[8] runWithPriority$1[9] reactPriorityToSchedulerPriority[9] Scheduler_runWithPriority[11] markCommitStarted? <- 本文重点介绍这里[11] markCommitStopped[7] ensureRootIsScheduled
需知在 performSyncWorkOnRoot 之前,React 已经创建好了 3 跟 Fiber 节点,
- 一个 FiberRootNode,
tag为LagacyRoot:它的containerInfo指向了div#root这个 DOM 元素 - 两个互为
alternate的 FiberNode,tag为HostRoot:它的stateNode指向了上面那个 FiberRootNode
我们来画一下它们的关系,
从图中可以看出 render 阶段 做的事情就是创建 FiberTree,
为一个标记为 WIP(workInProgress 变量)的 FiberNode 创建了多个子孙元素。
(在 render 阶段 执行过程中,workInProgress 这个全局变量的值会变,图中画的是它的初始值)
为了描述方便,图中略过了很多内容,例如 FiberNode 中的 updateQueue 等等。
2. 在大图中的位置
本文开始介绍 commit 阶段 的业务逻辑,
VSCode 插件 CodeTour 的安装可以参考 前一篇 文章,
相关仓库在这里 github: thzt/react-tour。
ReactDOM.render 的全流程在这里,
4.1.1 组件加载过程:函数组件(全流程)
我们要看这部分内容,即 commitRoot 的调用过程,
3. commitRoot 业务逻辑
一图胜千言,(函数前面的数字,表示缩进层次)
[7] commitRoot[8] runWithPriority$1[9] Scheduler_runWithPriority[10] eventHandler=commitRootImpl[11] markCommitStarted[11] invokeGuardedCallback <- 第一步[12] invokeGuardedCallbackImpl$1[13] dispatchEvent[14] func=commitBeforeMutationEffects[15] commitBeforeMutationLifeCycles[16] clearContainer <- div#root 的 textContext 置空[11] invokeGuardedCallback <- 第二步(这里要注意,看下文)[12] invokeGuardedCallbackImpl$1[13] dispatchEvent[14] func=commitMutationEffects[15] commitPlacement[16] insertOrAppendPlacementNodeIntoContainer <- 把 FiberNode <App /> 放到 div#root 中[17] insertOrAppendPlacementNodeIntoContainer <- 这是个递归函数,找到后代节点 stateNode 指向的 #text[18] appendChildToContainer[19] appendChild <- 实际操作 DOM,之后页面立即展示效果[11] invokeGuardedCallback <- 第三步[12] invokeGuardedCallbackImpl$1[13] dispatchEvent[14] func=commitLayoutEffects[11] markCommitStopped
我们看到 commitRoot 总共包含了三个步骤:
-
commitBeforeMutationEffects:将 div#root 置空 -
commitMutationEffects:将 #text 实际写入 DOM 中 -
commitLayoutEffects:当前示例,这一块没有特殊要说明的事情
commit 阶段 用 markCommitStarted 和 markCommitStopped 标记了开始和结束。
值得注意的是,commit 阶段 第三步 commitLayoutEffects 之前,
React 会将 FiberRootNode 的 current 属性指向创建好了 Fiber Tree。
(总共有两个 Fiber Tree,组件加载过程只创建一个)
如图所示,
参考
React 初窥门径(四):React 组件的加载过程(render 阶段)
VSCode: CodeTour
github: thzt/react-tour
4.1.1 组件加载过程:函数组件(全流程)
喜欢的朋友记得点赞、收藏、关注哦!!!
相关文章:
[FE] React 初窥门径(五):React 组件的加载过程(commit 阶段)
1. 回顾 前一篇文章我们看到,ReactDOM.render 总共包含这些步骤, 然后介绍了 performSyncWorkOnRoot 做的事情,它主要做了两件事, renderRootSync 可称之为 render 阶段:创建了一颗 Fiber Tree(包含 html …...
Linux(Centos 7.6)命令详解:vim
1.命令作用 vi/vim 是Linux 系统内置不可或缺的文本编辑命令,vim 是vi 的加强版本,兼容vi 的所有指令,不仅能编辑文本,而且还具有shell 程序编辑的功能,可以不同颜色的字体来辨别语法的正确性。 2.命令语法 usage: …...
Kubernetes Pod网络组件解析与选型指南
前言 在Kubernetes集群中,Pod网络插件是支撑容器间通信的核心基础设施。它决定了Pod如何跨节点互联、如何与外部服务交互,甚至如何实现网络安全策略。本文将从技术原理、主流方案对比到选型实践,全方位解析Pod网络组件的设计哲学与落地策略。…...
java环境部署
java环境部署 一、准备工作 jrejdkeclipse jdk下载:21和1.8-----官网:Oracle:Java 下载 |神谕 该处选择要依据自身的系统类型选择下载 idea的下载安装:IntelliJ IDEA | Other Versions 二、安装 三、环境配置 四、使用 五、i…...
100天精通Python(爬虫篇)——第115天:爬虫在线小工具_Curl转python爬虫代码工具(快速构建初始爬虫代码)
文章目录 一、curl是什么?二、爬虫在线小工具(牛逼puls)三、实战操作 一、curl是什么? 基本概念:curl 支持多种协议,如 HTTP、HTTPS、FTP、SFTP 等,可用于从服务器获取数据或向服务器发送数据&a…...
查看k8s集群的资源使用情况
查看Kubernetes(k8s)集群的资源使用情况有多种方法,以下是一些常见的方式: 使用kubectl命令行工具 查看节点资源使用情况 kubectl top nodes命令可以显示集群中各个节点的CPU和内存使用情况。例如: NAME …...
【渗透测试】基于时间的盲注(Time-Based Blind SQL Injection)
发生ERROR日志告警 查看系统日志如下: java.lang.IllegalArgumentException: Illegal character in query at index 203: https://api.weixin.qq.com/sns/jscode2session?access_token90_Vap5zo5UTJS4jbuvneMkyS1LHwHAgrofaX8bnIfW8EHXA71IRZwsqzJam9bo1m3zRcSrb…...
Electron应用中获取设备唯一ID和系统信息
让我创建一篇关于如何在Electron应用中获取设备唯一ID和系统信息,并在登录时使用这些信息的博客文章。我将确保步骤明确、条理清晰,适合初学者和有经验的开发者。 这篇博客应包含以下部分: 介绍 - 为什么需要获取设备信息前提条件和安装依赖…...
python-leetcode-解决智力问题
2140. 解决智力问题 - 力扣(LeetCode) 这道题是一个典型的 动态规划(Dynamic Programming, DP) 问题,可以使用 自底向上 的方式解决。 思路 定义状态: 设 dp[i] 表示从第 i 题开始,能获得的最高…...
SpireCV荣获Gitee 最有价值开源项目称号
什么是GVP? GVP全称Gitee Valuable Project,意思为Gitee最有价值开源项目。作为GVP称号的获得者,SpireCV在开源社区中展现出了卓越的实力和影响力,为开源软件的发展和推广做出了积极的贡献。 这一荣誉不仅充分肯定了过去阿木实验…...
数据结构基础(一)
文章目录 1 数据结构基础1.1 什么是程序?1.2 数据、数据元素、数据项、数据对象1.3 基本的逻辑结构 2 算法效率2.1 时间复杂度2.1.1 循环执行次数2.1.2 大O(n)表示法 2.2 空间复杂度 1 数据结构基础 1.1 什么是程序? 程序 数据结构 + 算…...
⭐算法OJ⭐N-皇后问题 II【回溯剪枝】(C++实现)N-Queens II
⭐算法OJ⭐N-皇后问题【回溯剪枝】(C实现)N-Queens 问题描述 The n-queens puzzle is the problem of placing n n n queens on an n n n \times n nn chessboard such that no two queens attack each other. Given an integer n, return the num…...
项目管理工具 Maven
目录 1.Maven的概念 1.1什么是Maven 1.2什么是依赖管理 1.3什么是项目构建 1.4Maven的应用场景 1.5为什么使用Maven 1.6Maven模型 2.初识Maven 2.1Maven安装 2.1.1安装准备 2.1.2Maven安装目录分析 2.1.3Maven的环境变量 2.2Maven的第一个项目 2.2.1按照约…...
国产编辑器EverEdit - 宏功能介绍
1 宏 1.1 应用场景 宏是一种重复执行简单工作的利器,可以让用户愉快的从繁琐的工作中解放出来,其本质是对键盘和菜单的操作序列的录制,并不会识别文件的内容,属于无差别无脑执行。 特别是对一些有规律的重复按键动作,…...
CODEGEN:一种基于多轮对话的大型语言模型编程合成方法
【摘要】 该论文于ICLR 2023会议上发表,标题为“CODEGEN:用于编程的大型语言模型”,由Salesforce Research团队撰写。论文提出的CODEGEN是一个大型语言模型系列,旨在通过自然语言和编程语言数据进行训练,以实现程序合成。以下是论文的主要贡献和关键发现的总结: 核心贡献…...
利用后缀表达式构造表达式二叉树的方法
后缀表达式(逆波兰表达式)是一种将运算符放在操作数之后的表达式表示法。利用后缀表达式构造表达式二叉树的方法主要依赖于栈结构。 转换步骤 初始化 创建一个空栈。 遍历后缀表达式 对后缀表达式的每个符号依次处理: 遇到操作数 如果当前符…...
深度学习笔记——基础部分
深度学习是一种机器学习的方式,通过模仿人脑吃力信息的方式,使用多层神经网络来学习数据的复杂模式和特征。 深度学习和机器学习的区别: 在机器学习中,特征提取通常需要人工设计和选择,依赖于领域专家的知识来确定哪些…...
“双碳”背景下,企业应该如何提升能源效率?
在当今竞争激烈的市场环境中,企业不仅需要优化成本,还需积极响应国家的能源政策,减少对环境的影响。提升工业能源效率正是实现这一双重目标的关键。中国近年来大力推进“双碳”目标(碳达峰、碳中和),并出台…...
BambuStudio学习笔记:MarchingSquares类
# Marching Squares算法头文件分析## 文件结构概览 cpp #ifndef MARCHINGSQUARES_HPP #define MARCHINGSQUARES_HPP // 包含标准库头文件 // 命名空间定义 namespace marchsq {// 基础数据结构struct Coord;using Ring std::vector<Coord>;// 栅格适配器模板template<…...
重生之我在 CSDN 学习 KMP 算法
深入理解 KMP 算法:高效字符串匹配的利器 一、KMP 算法的由来及其解决的问题 在计算机科学领域,字符串处理是一项极为常见且基础的任务。其中,字符串匹配问题更是频繁出现,例如在文本编辑器中查找特定单词、在生物信息学中搜索 D…...
文献学习——考虑混合储能系统选择的基于改进蜂群算法的热电联产微网多目标经济优化调度
摘要:在考虑混合储能系统模型选择的基础上,基于改进的人工蜂群算法(ABC),建立了冷热电联产微电网经济优化的多目标调度模型。为了对以往研究中的单目标模型进行升级,将模型的优化目标设定为微电网的日发电调…...
GPTQ - 生成式预训练 Transformer 的精确训练后压缩
GPTQ - 生成式预训练 Transformer 的精确训练后压缩 flyfish 曾经是 https://github.com/AutoGPTQ/AutoGPTQ 现在是https://github.com/ModelCloud/GPTQModel 对应论文是 《Accurate Post-Training Quantization for Generative Pre-trained Transformers》 生成式预训练Tr…...
nnMamba:基于状态空间模型的3D生物医学图像分割、分类和地标检测
摘要 本文提出了一种基于状态空间模型(SSMs)的创新架构——nnMamba,用于解决3D生物医学图像分割、分类及地标检测任务中的长距离依赖建模难题。nnMamba结合了卷积神经网络(CNN)的局部特征提取能力与SSMs的全局上下文建…...
安科瑞新能源充电桩解决方案:驱动绿色未来,赋能智慧能源
安科瑞顾强 引言 在“双碳”目标与新能源汽车产业高速发展的双重驱动下,充电基础设施正成为能源转型的核心环节。安科瑞电气股份有限公司凭借在电力监控与能效管理领域20余年的技术积淀,推出新一代新能源充电桩解决方案,以智能化、高兼容性…...
使用开源OPUS-MT模型进行文本翻译(python)
1. 环境准备 pip install transformers 2. 下载机器翻译模型: 2.1 代码从hugging face平台下载 from transformers import MarianMTModel, MarianTokenizer# 指定模型名称 model_name "Helsinki-NLP/opus-mt-zh-en" # 中译英模型# 下载并保存分词器到…...
通过 Docker openssl 容器生成生成Nginx证书文件
使用 alpine/openssl 镜像生成证书 1. 拉取容器 [rootlocalhost ~]# docker run --rm alpine/openssl version OpenSSL 3.3.3 11 Feb 2025 (Library: OpenSSL 3.3.3 11 Feb 2025)2. 运行 alpine/openssl 生成证书(Nginx) # 生成1个.key私钥文件&#…...
Elastic如何获取当前系统时间
文章目录 1. 使用 _ingest.timestamp 在 Ingest Pipeline 中获取当前时间2. 使用 Painless Script 获取当前时间3. 使用 now 关键字在查询中获取当前时间4. 使用 date 类型字段的默认值5. 使用 Kibana 的 Dev Tools 查看当前时间6. 使用 date 聚合获取当前时间7. 使用 Elastics…...
MLT媒体程序框架03:滤镜——loudness
EBU R.128协议 引用链接 EBU的全称为European Broadcasting Union ,既欧洲广播联盟,为欧洲与北非各广播业者(包含广播电台与电视台)的合作组织,成立于1950年2月12日,有五十多个正式加盟国,总部位于瑞士日内瓦,目前中国…...
jenkins配置连接k8s集群
jenkins配置连接k8s集群 前言 我这边jenkins是在一个服务器里面,k8s集群在其他服务器,实现连接 首先jenkins下载有k8s插件 进入配置页面 获取k8s-api-server地址 对应k8s服务器执行 kubectl config view --minify -o jsonpath{.clusters[0].cluste…...
如何选择缓存模式?
如何选择缓存模式 当一个系统引入缓存后,最大的挑战之一便是如何确保缓存与后端数据库的一致性。目前,常见的解决方案主要有Cache Aside、Read/Write Throught和Write Back这三种缓存更新策略。 Read/Write Throught策略 读操作方面,如果缓…...
