当前位置: 首页 > news >正文

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基本均是多核的,真正的服务器&#xf…...

基于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,分别代表题目中操作的两个元素。 输出: 按顺序输出收养动物的序列,编号之间以空格间隔。 源代码&#xff…...

Kotlin 基础教程一

Kotlin 基本数据类型 Java | Kotlin byte Byte short Short int Int long Long float Float double Double boolean Boolean c…...

数据结构笔记--前缀树的实现

1--前缀树的实现 前缀树的每一个节点拥有三个成员变量&#xff0c;pass表示有多少个字符串经过该节点&#xff0c;end表示有多少个字符串以该节点结尾&#xff0c;nexts表示该字符串可以走向哪些节点&#xff1b; #include <iostream> #include <unordered_map>str…...

C/C++时间获取函数

time.h包含C/C中用于获取时间&#xff0c;和时间转换方面的函数。 1、time() 函数 time_t time(time_t *seconds) 返回自&#xff08;1970-01-01 00:00:00 UTC&#xff09;起经过的时间&#xff0c;以秒为单位。如果 seconds 不为空&#xff0c;则返回值也存储在变量 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函数&#xff1a; 使用to_days(start_date) to_days(now())的方式是一种常见的…...

NAS搭建指南一——服务器的选择与搭建

一、服务器的选择 有自己的本地的公网 IP 的请跳过此篇文章按需求选择一个云服务器&#xff0c;目的就是为了进行 frp 的搭建&#xff0c;完成内网穿透我选择的是腾讯云服务器&#xff0c;我的配置如下&#xff0c;仅供参考&#xff1a; 4. 腾讯云服务器官网地址 二、服务器…...

录音会议纪要整理不同使用场景,实用口碑选择建议

针对不同场景的录音整理需求&#xff08;短录音、中长录音、长内容深度整理&#xff09;&#xff0c;本文基于实际使用体验&#xff0c;分享不同场景下的工具选择建议与使用心得。一、场景一&#xff1a;短录音&#xff08;15-60分钟&#xff0c;发音清晰&#xff09;典型场景&…...

为内部知识库问答机器人接入Taotoken多模型增强回答效果

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 为内部知识库问答机器人接入Taotoken多模型增强回答效果 构建一个高效的企业内部知识库问答机器人&#xff0c;核心挑战在于如何让…...

关于psthon问题

我想问问各位 我python可以查到 但是我的bit文件查不到python怎么回事...

Jupyter Notebook里跑argparse脚本总报错?一个空列表参数搞定ipykernel_launcher.py error

Jupyter Notebook中argparse报错的终极解决方案&#xff1a;空列表参数实战解析在数据科学和机器学习的工作流中&#xff0c;Jupyter Notebook因其交互式特性成为众多研究者的首选工具。然而&#xff0c;当我们尝试在Notebook中运行那些原本为命令行设计的Python脚本时&#xf…...

16个分片+2副本:pg_shard的master_create_worker_shards最佳实践

16个分片2副本&#xff1a;pg_shard的master_create_worker_shards最佳实践 【免费下载链接】pg_shard ATTENTION: pg_shard is superseded by Citus, its more powerful replacement 项目地址: https://gitcode.com/gh_mirrors/pg/pg_shard pg_shard作为PostgreSQL的分…...

风控系统如何全维度识别爬虫:IP、账号与行为的协同决策机制

1. 这不是“反爬失败”&#xff0c;而是风控系统在对你做全维度画像你写完一段 requests BeautifulSoup 的代码&#xff0c;本地跑通了&#xff0c;开开心心部署到服务器&#xff0c;结果第二天早上发现&#xff1a;所有请求返回 403&#xff0c;日志里全是空响应&#xff1b;…...

LeaguePrank:5分钟打造个性化英雄联盟客户端,段位头像随心换!

LeaguePrank&#xff1a;5分钟打造个性化英雄联盟客户端&#xff0c;段位头像随心换&#xff01; 【免费下载链接】LeaguePrank 项目地址: https://gitcode.com/gh_mirrors/le/LeaguePrank 厌倦了千篇一律的英雄联盟客户端界面&#xff1f;想向好友展示王者段位却还在白…...

AI算法工程师如何进行模型部署?这2个工具+3个技巧,快速上线

对于软件测试从业者来说&#xff0c;模型部署并不是一个陌生的概念——随着AI功能逐渐渗透到各类应用软件中&#xff0c;测试工程师不仅需要验证模型输出的准确性&#xff0c;更需要理解部署流程对模型稳定性、响应速度和结果一致性的影响。很多测试同学会有这样的困惑&#xf…...

如何快速实现U盘文件自动备份:USBCopyer终极指南

如何快速实现U盘文件自动备份&#xff1a;USBCopyer终极指南 【免费下载链接】USBCopyer &#x1f609; 用于在插上U盘后自动按需复制该U盘的文件。”备份&偷U盘文件的神器”&#xff08;写作USBCopyer&#xff0c;读作USBCopier&#xff09; 项目地址: https://gitcode.…...

WaveTools鸣潮工具箱:3步完成游戏性能优化与配置调校的完整指南

WaveTools鸣潮工具箱&#xff1a;3步完成游戏性能优化与配置调校的完整指南 【免费下载链接】WaveTools &#x1f9f0;鸣潮工具箱 项目地址: https://gitcode.com/gh_mirrors/wa/WaveTools WaveTools鸣潮工具箱是一款专为《鸣潮》玩家设计的开源性能优化工具&#xff0c…...