React源码解析18(4)------ completeWork的工作流程【mount】
摘要
经过上一章,我们得到的FilberNode已经具有了child和return属性。一颗Filber树的结构已经展现出来了。
那我们最终是想在页面渲染真实的DOM。所以我们现在要在completeWork里,构建出一颗离屏的DOM树。
之前在说FilberNode的属性时,我们提到过一个属性stateNode。它就是用来保存每个FilberNode的真实DOM。
OK,现在我们开干,准备实现completeWork。
1.completeWork方法
在completeWork方法里,我们将刚才准备好的FilberNode(最外层的)传进来。
completeWork方法也一定是一个递归的过程,每次调用的时候我们要判断当前的FilberNode的tag类型。
在判断当前的FilberNode是否具有stateNode,如果有,就说明不是第一次更新。如果没有,就说明此时是mount第一次渲染的阶段。
export const completeWork = (filberNode) => {console.log(filberNode);const tag = filberNode.tagswitch (tag) {case HostComponent: {if(filberNode.stateNode !== null){//更新}else{completeHostComponent(filberNode)}break;}case HostText: {break;}case HostRoot: {}}
}
2.创建真实DOM
拿到每个FilberNode后,如果他是HostComponent类型的。我们实现出completeWork方法。
首先我们可以通过拿到FilberNode的type(div,span),知道真实DOM的类型,通过document的方法创建出对应的element。
然后再通过return属性,拿到当前节点的父节点。并且在父节点的stateNode中,添加创建好的element。
function completeHostComponent(filberNode) {const type = filberNode.type;const element = document.createElement(type);filberNode.stateNode = element;const parent = filberNode.return;if(parent && parent.stateNode && parent.tag === HostComponent) {parent.stateNode.appendChild(element)}completeWork(filberNode.child)
}
对于HostText类型,我们可以直接创建文本节点,然后挂载在stateNode上面即可:
function completeHostText(filberNode) {const content = filberNode.pendingProps;const element = document.createTextNode(content)filberNode.stateNode = elementconst parent = filberNode.return;if(parent && parent.stateNode && parent.tag === HostComponent) {parent.stateNode.appendChild(element)}
}
这里值得注意的是,在创建真实DOM的时候,这里并没有处理props相关的内容。只创建了对应的DOM结构。
3.挂载finishedWork
最后我们将执行完beginWork和completeWork的FilberRootNode。挂载在hostRootFilber上面,
function updateContainer(root, element) {const hostRootFilber = root.current;const update = createUpdate(element);hostRootFilber.updateQueue = createUpdateQueue()enqueueUpdate(hostRootFilber.updateQueue, update);beginWork(hostRootFilber);completeWork(hostRootFilber);root.finishedWork = hostRootFilber;
}
4.问题
这里我们打印一下root,可以看到:

root的current和finishedWork其实是一模一样的,但React其实并非是这样处理的。经过beginWork和completeWork处理的节点,并不是最外层的FilberNode,而是它的alternate。
所以我们调用beginWork和completeWork处理的应该是FilberNode的alternate。
5.效果
为了看到效果我们可以写一个方法,当然这个方法里面内容不可能这没少。但是我们可以先实现一下:
export function commitWork(filberRootNode) {const container = filberRootNode.container;const child = filberRootNode.finishedWork.child.stateNode;container.appendChild(child)
}
然后再beginWork和completeWork执行完后,执行这个方法。
就可以看到页面正产渲染节点了。
相关文章:
React源码解析18(4)------ completeWork的工作流程【mount】
摘要 经过上一章,我们得到的FilberNode已经具有了child和return属性。一颗Filber树的结构已经展现出来了。 那我们最终是想在页面渲染真实的DOM。所以我们现在要在completeWork里,构建出一颗离屏的DOM树。 之前在说FilberNode的属性时,我们…...
Kafka: 详解、使用教程和示例
Kafka: 详细介绍、使用教程和示例 什么是 Kafka? Kafka 是一个分布式的流处理平台,最初由 LinkedIn 开发,现已成为 Apache 基金会的顶级项目。它以高吞吐量、可靠性和可扩展性而闻名,被广泛应用于实时数据传输、日志收集、事件处…...
【LeetCode周赛】LeetCode第358场周赛
LeetCode第358场周赛 数组中的最大数对和翻倍以链表形式表示的数字限制条件下元素之间的最小绝对差 数组中的最大数对和 给你一个下标从0开始的整数数组nums。请你从nums中找出和最大的一对数,且这两个数数位上最大的数字相等。 返回最大和,如果不存在满…...
Node.js学习笔记-04
这第九章也是个大重点 九、玩转进程 Node在选型时决定在V8引擎之上构建,也就意味着它的模型与浏览器类似。 本章关于进程的介绍和讨论将会解决如下两个问题: 单进程单线程并非完美,如今CPU基本均是多核的,真正的服务器…...
基于dbn+svr的交通流量预测,dbn详细原理
目录 背影 DBN神经网络的原理 DBN神经网络的定义 受限玻尔兹曼机(RBM) DBN+SVR的交通流量预测 基本结构 主要参数 数据 MATALB代码 结果图 展望 背影 DBN是一种深度学习神经网络,拥有提取特征,非监督学习的能力,是一种非常好的分类算法,本文将DBN+SVR用于交通流量预测…...
【第一阶段】kotlin中反引号中的函数名特点
在kotlin中可以直接中文定义函数,使用反引号进行调用 eg: fun main() {2023年8月9日定义的函数(5) }private fun 2023年8月9日定义的函数(num:Int){println("反引号的用法$num") }执行结果 在Java中is,in可以定义方法,但是在kotlin中is,in是…...
数据分析-python学习 (1)numpy相关
内容为:https://juejin.cn/book/7240731597035864121的学习笔记 导包 import numpy as np numpy数组创建 创建全0数组,正态分布、随机数组等就不说了,提供了相应的方法通过已有数据创建有两种 arr1np.array([1,2,3,4,5]) 或者datanp.loadt…...
数据库的游标
数据库的游标(Cursor)是用于在数据库中进行数据操作的一个控制结构。它类似于在编程语言中使用的指针或迭代器,用于遍历数据库结果集并在结果集上执行各种操作。 游标允许我们在数据库查询的结果集中逐行移动,并对每一行执行特定…...
【设计模式】前端控制器模式
前端控制器模式(Front Controller Pattern)是用来提供一个集中的请求处理机制,所有的请求都将由一个单一的处理程序处理。该处理程序可以做认证/授权/记录日志,或者跟踪请求,然后把请求传给相应的处理程序。以下是这种…...
SQL | 过滤数据
4-过滤数据 4.1-使用WHERE子句 数据根据 WHERE 子句中指定的搜索条件进行过滤。WHERE 子句在表名( FROM 子句)之后给出。 select prod_name,prod_price from products where prod_price 3.49; 上述语句查询价格为3.49的行,然后输出名字和…...
【力扣每日一题】2023.8.13 合并两个有序数组
目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 题目给我们两个升序数组,让我们合并它们,要求合并之后仍然是升序,并且这个合并操作是在数组1原地修改…...
数据结构篇七:排序
文章目录 前言1.插入排序1.1 基本思想1.2 代码实现1.3 特性总结 2.希尔排序2.1 基本思想2.2 代码实现2.3 特性总结 3. 选择排序3.1 基本思想3.2 代码实现3.3 特性总结 4. 堆排序4.1 基本思想4.2 代码实现4.3 特性总结 5. 冒泡排序5.1 基本思想5.2 代码实现5.3 特性总结 6. 快速…...
Vue组件的边界情况
01.$root; 访问组件的根实例;用的不多,基本上在vuex上进行数据操作; 02.$parent/$children; 可以获得父组件或者子组件上边的数据;一般不建议使用$parent,因为如果获取这个值进行修改的话,也会更改父组件上…...
less、sass的使用及其区别
CSS预处理器 CSS 预处理器是一种扩展了原生 CSS 的工具,它们添加了一些编程语言的特性,以便更有效地编写、组织和维护样式代码。预处理器允许开发者使用变量、嵌套、函数、混合等功能,从而使 CSS 更具可读性、可维护性和重用性,特…...
[保研/考研机试] 猫狗收容所 C++实现
题目描述: 输入: 第一个是n,它代表操作序列的次数。接下来是n行,每行有两个值m和t,分别代表题目中操作的两个元素。 输出: 按顺序输出收养动物的序列,编号之间以空格间隔。 源代码ÿ…...
Kotlin 基础教程一
Kotlin 基本数据类型 Java | Kotlin byte Byte short Short int Int long Long float Float double Double boolean Boolean c…...
数据结构笔记--前缀树的实现
1--前缀树的实现 前缀树的每一个节点拥有三个成员变量,pass表示有多少个字符串经过该节点,end表示有多少个字符串以该节点结尾,nexts表示该字符串可以走向哪些节点; #include <iostream> #include <unordered_map>str…...
C/C++时间获取函数
time.h包含C/C中用于获取时间,和时间转换方面的函数。 1、time() 函数 time_t time(time_t *seconds) 返回自(1970-01-01 00:00:00 UTC)起经过的时间,以秒为单位。如果 seconds 不为空,则返回值也存储在变量 seconds …...
sql中判断日期是否是同一天
sql中判断日期是否是同一天的sql sql: select id,product_id,seckill_price,stock_count,time,intergral,start_date from t_seckill_product where to_days(start_date) to_days(now()) to_days函数: 使用to_days(start_date) to_days(now())的方式是一种常见的…...
NAS搭建指南一——服务器的选择与搭建
一、服务器的选择 有自己的本地的公网 IP 的请跳过此篇文章按需求选择一个云服务器,目的就是为了进行 frp 的搭建,完成内网穿透我选择的是腾讯云服务器,我的配置如下,仅供参考: 4. 腾讯云服务器官网地址 二、服务器…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
