React源码解析18(2)------ FilberNode,FilberRootNode结构关系

news2024/9/28 15:18:46

摘要

在上一篇,我们实现了通过JSX转换为ReactElement的方法,也看到了转换后React元素的结构。但是这个React元素,并不能很清楚的表达组件之间的关系,以及属性的处理。

所以在React内部,会将所有的React元素转换为Filber树。而这一章节,主要就是简单描述一下FilberNode的结构。

首先看一下一颗Filber树是什么样子的:

在这里插入图片描述

在这张图里,出了filberRootNode,其他的节点都是FilberNode类型,hostRootFilber就是最外层的FilberNode。

在项目里面,当我们调用 **ReactDOM.createRoot(root)**方法的时候,就会创建出上面的FilberRootNode和hostRootFilber。并且将二者之间的指向关系确定。

1.FilberNode

首先,说一下一个FilberNode都具有什么属性(这里有省略)。

【1】tag属性

我们回到React元素,可以知道React元素的type可以是,一个div,span等,也可以是一段文本text,也可以是一个函数function(函数类型组件)。

在FilberNode里面,对应的就是tag属性,这里我们定义好tag都可以是什么属性:

const FunctionComponent = 'FunctionComponent'; //对应函数
const HostRoot= 'HostRoot'; //对应hostRootFilber
const HostComponent= 'HostComponent'; //对应div
const HostText = 'HostText'; //对应文本节点

这里面多了一个HostRoot类型,对应的是最外层FilberNode(也就是HostRootFilber)的tag。

【2】key属性

对应的就是ReactElement中的key。

【3】stateNode属性

这个属性就比较重要了,我们思考一下,不管React内部怎么做,最终的结果一定是生成真实的DOM。
而这个属性就是保存每个FilberNode的真实DOM。
hostRootFilber的stateNode指向最外面的filberRootNode。

【4】type属性

对应的就是ReactElement中的type。

【5】ref属性

对应的就是ReactElement的ref属性

【6】return , sibling, child,index属性

前三个属性,分表代表FilberNode的父节点,兄弟节点,子节点。通过这三个属性来确定整颗Filber树的结构。
index属性代表的就是,同级节点的位置。例如一个父节点下面有很多子节点,index就代表它们的索引。

【7】alternate属性

在React内部,会维护两棵Filber树,current树是用来渲染真实DOM,而B树是在更新时,通过计算生成的新的Filber树。每次更新都会用新的Filber树替换current树,成为新的current树。
所以每个FilberNode都有一个alternate属性,用来指向另一棵树的对应节点。

【8】pendingProps属性

用来表示FilberNode初始的props值

【9】memoizedProps属性

用来表示更新后FilberNode的props值

【10】memoizedState属性

和更新相关的属性。

目前我们先准备这些属性,等后面如果有需要了再加,现在我们实现FilberNode类:

export class FilberNode {
	constructor(tag, pendingProps, key) {
		this.tag = tag;
		this.key = key;
		this.stateNode = null;
		this.type = null;

		this.return = null;
		this.sibling = null;
		this.child = null;
		this.index = 0;

		this.ref = null;

		this.pendingProps = pendingProps;
		this.memoizedProps = null;
		this.memoizedState = null;
		this.alternate = null;
	}
}

2.FilberRootNode

我们最开始说过,FilberRootNode并非是FilberNode。它有着自己的数据结构,现在我们说一下FilberRootNode具有的属性:

【1】container属性

对应的就是挂载的React元素,例如 项目中的App 。

【2】current属性

指向最外层的FilberNode,也就是hostRootFilber。而hostRootFilber的stateNode指向FilberROOtNode。

【3】finishWork属性

该属性对应的是已经处理完后的最外层的FilberNode。

现在我们实现对应的FilberRootNode类:

export class FilberRootNode {
	constructor(container, hostRootFilber) {
		this.container = container;
		this.current = hostRootFilber;
		hostRootFilber.stateNode = this;
		this.finishedWork = null;
	}
}

它的构造函数接受两个参数,分别对应的就是hostFilberRoot以及App。在构造函数中,表明自身和hostFilberRoot之间的关系。

3.定义ReactDOM

现在我们已经有了FilberNode和FilberRootNode的数据结构。现在我们来回想一下我们在项目中是怎么使用ReactDOM的。

const root = document.getElementById(‘root’)
ReactDOM.createRoot(root).render()

也就是我们要实现的ReactDOM中,要有createRoot方法,同时该方法返回一个render方法:


function createRoot() {
  
  return {
    render() {

    }
  }
}

const ReactDOM = {
  createRoot
}

export default ReactDOM

4.实现createRoot方法

这一篇文章只是为了定义好开头,所以我们只实现基本的结构。
在调用createRoot方法后,我们会创建FilberRootNode对象,这里面我们封装成一个方法,
createContainer方法:

function createContainer(root) {
  const hostRootFilber = new FilberNode(HostRoot, {}, '')
  return new FilberRootNode(root, hostRootFilber);
}

5.小节,测试

这一篇主要就说这些,通过构建filberNode和filberRootNode来表示整个Filber树的结构。
测试代码:


import { FilberNode, FilberRootNode } from "./filberNode"
import {HostComponent, HostRoot, HostText, FunctionComponent} from './filberNode'

function createRoot(root) {
  const filberRootNode = createContainer(root);
  console.log(filberRootNode);
  return {
    render() {

    }
  }
}

function createContainer(root) {
  const hostRootFilber = new FilberNode(HostRoot, {}, '')
  return new FilberRootNode(root, hostRootFilber);
}

const ReactDOM = {
  createRoot
}

export default ReactDOM

在控制台我们可以看到二者之间的关系:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/853328.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

银行高效办公神技,看完跪了!

在现代社会中,银行作为金融体系的关键组成部分,不仅需要保障日常的业务运作,还必须在电力故障等紧急情况下保持连续性。 蓄电池作为一种关键设备,需要持续的监控和维护,以确保其可靠性和性能。因此,银行网点…

Salesforce 助理认证和管理员认证有何区别?备考者应如何选择?

随着Salesforce生态系统对专业人员的需求不断增长,获得相关认证对于寻求职业发展的从业者来说至关重要。 对于刚接触Salesforce平台的人而言,Salesforce助理认证和Salesforce管理员认证是两个比较基础的认证。这两个认证有什么区别呢?从业者…

python爬虫实战(1)--爬取新闻数据

想要每天看到新闻数据又不想占用太多时间去整理,萌生自己抓取新闻网站的想法。 1. 准备工作 使用python语言可以快速实现,调用BeautifulSoup包里面的方法 安装BeautifulSoup pip install BeautifulSoup完成以后引入项目 2. 开发 定义请求头&#xf…

国内数字藏品行业现状分析

国内数字藏品行业现状分析 NFT与国内数字藏品的区别 数字藏品是NFT的一种应用形式,国内数字藏品与NFT本质区别在于国内数字藏品不具备NFT的金融属性及社交属性,与虚拟货币划清了明确的界限。 国内数字藏品所处的发展阶段 发展阶段(成长期)。 由于加密…

24届近5年中国计量大学自动化考研院校分析

今天给大家带来的是中国计量大学控制考研分析 满满干货~还不快快点赞收藏 一、中国计量大学 学校简介 中国计量大学是我国质量监督检验检疫行业唯一的一所本科院校,是一所计量标准质量检验检疫特色鲜明、多学科协调发展的普通高校,坐落于…

springboot添加swagger和knife简化接口测试

1、添加依赖 <!-- 接口测试包--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><!--排除swagger2的annotations和models依赖&#xff0c;然后再引入1.5.21版本的annotations和models…

Pr2022安装插件beat edit安装之后无法加载音乐怎么办?

你运行设置不对&#xff0c;安装好后试试管理员权限运行。 安装好插件后点击上方的窗口&#xff0c;然后再在里面找到扩展&#xff0c;继续点开里面有个BeatEdit&#xff0c;就是插件本身&#xff0c;点开。先选择一个加载音乐的选项&#xff0c;载入音乐先。这个时候可以按下…

一篇文章教会你什么是Linux进程控制

Linux进程控制 进程创建1.fork函数初识1.1那么fork创建子进程时&#xff0c;操作系统都做了什么呢&#xff1f;1.2 父子进程和CPU中的EIP&#xff08;指令指针&#xff09;之间存在一定的关系1.3 fork的常规用法有哪些&#xff1f;1.4 fork调用失败的原因有哪些&#xff1f; 2.…

TLS洪水攻击是什么,当网络加密成为一种负担怎么办?

今天&#xff0c;我们将深入研究一种典型的DDOS攻击类型——TLS洪水攻击&#xff0c;TLS&#xff08;传输层安全&#xff09;洪水攻击可以淹没大多数DDoS防护解决方案。因此如果您使用了错误的解决方案&#xff0c;意味着您的Web应用程序面临很大的风险&#xff01; 今天将由火…

云端同步、高效无界:5款免费的跨平台思维导图软件推荐!

思维导图是一种以图形化方式表示思想、概念或任务的方法&#xff0c;可以帮助用户梳理思维、提高记忆和理解。在工作中&#xff0c;思维导图可以用于会议记录、任务规划、项目管理等&#xff0c;帮助提高工作效率和团队协作能力&#xff1b;在学习中&#xff0c;思维导图可以用…

HA3 SQL样本实验:一种混合计算查询的全新样本解决方案

作者&#xff1a;陆唯一(芜霜) HA3&#xff08;对外开源代号&#xff1a;Havenask &#xff09;是阿里智能引擎团队自研的大规模分布式检索系统&#xff0c;广泛应用于阿里内部的搜索业务&#xff0c;是十多年来阿里在电商领域积累下来的核心竞争力产品。Ha3 SQL 是在原有Ha3引…

IDEA简单拷贝一份新项目记录

IDEA简单拷贝项目记录 拷贝后改项目名&#xff0c;然后iml 配置文件改项目名&#xff0c;然后 .idea 中的compiler.xml 里面的name标签改项目名。 就可以了

Sentieon|应用教程:利用Sentieon Python API引擎为自研算法加速

背景 Sentieon套装中所有模块的速度都远超对应开源软件的数倍至数十倍&#xff0c;用户在使用这些模块的同时&#xff0c;有时也希望Sentieon团队可以帮助加速自己开发的定制化软件。为了帮助这些用户能在自研软件上享受到Sentieon模块的速度&#xff0c;我们开发了Python API…

续签四年的榜一大哥,打动他的竟是

今天要聊的是一位来自有福之州的医疗客户&#xff0c;从产品落地至今一直使用&#xff0c;连续四年不断续约&#xff0c;名副其实的榜一大哥。最初打动用户的&#xff0c;来自技术团队的服务能力&#xff0c;以及客户对新生产品期待和支持&#xff0c;而五年来不离不弃&#xf…

vue 点击顶部tab重新请求列表

我们点击 1 2 来回切换时,发现客户经理的列表不会重新请求(菜单中含有客户经理) 这时我们添加以下代码就可以了 watch: {$route(route) {this.getList()}},/** 查询客户经理列表 */getList() {this.loading true;listManager(this.queryParams).then(response > {this.mana…

低代码如何实现高效率开发?

在高度变化的市场环境下&#xff0c;企业亟需形成以数据为驱动的新型生产运营方式&#xff0c;提升价值、创新模式、降低成本&#xff0c;以建立新一轮的核心竞争优势。在此背景下&#xff0c;数字化转型成为了最具确定性的时代浪潮&#xff0c;企业纷纷拥抱低代码开发平台&…

NSS [UUCTF 2022 新生赛]ez_upload

NSS [UUCTF 2022 新生赛]ez_upload 考点&#xff1a;Apache解析漏洞 开题就是标准的上传框 起手式就是传入一个php文件&#xff0c;非常正常的有过滤。 .txt、.user.ini、.txxx都被过滤了&#xff0c;应该是白名单或者黑名单加MIME过滤&#xff0c;只允许.jpg、.png。 猜测二…

UVSLED透明屏,在商业广告中,有哪些应用表现?

UVSLED透明屏是一种新型的显示屏技术&#xff0c;它采用了UVSLED&#xff08;Ultraviolet Shortwave Light Emitting Diode&#xff09;作为光源&#xff0c;具有高亮度、高对比度和高色彩饱和度的特点。 UVSLED透明屏可以实现透明显示效果&#xff0c;使得观众可以同时看到屏…

uniapp实现自定义导航内容高度居中(兼容APP端以及小程序端与胶囊对齐)

①效果图如下 1.小程序端与胶囊对齐 2.APP端内容区域居中 注意&#xff1a;上面使用的是colorui里面的自定义导航样式。 ②思路&#xff1a; 1.APP端和小程序端走不同的方法&#xff0c;因为小程序端要计算不同屏幕下右侧胶囊的高度。 2.其次最重要的要清晰App端和小程序端…

如何利用合同管理系统降低企业的风险和损失

合同管理系统是企业内部的重要工具&#xff0c;它可以帮助企业有效降低风险和损失。通过规范和集中管理企业与其他主体之间的合同&#xff0c;合同管理系统可以提供一系列的功能和工具&#xff0c;帮助企业更好地管理合同并减少潜在的法律纠纷。 1. 合同信息集中管理 合同管理…