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

摘要

在上一篇,我们实现了通过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.rhkb.cn/news/82893.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】详解进程状态之僵尸进程——孤儿进程

目录 🌞专栏导读 🌛什么是进程 ⭐什么是PCB? 🌛查看进程 🌛如何通过系统调用查看进程PID 🌛fork 🌞认识进程状态 🌛查看进程状态 🌛R状态 ⭐例如&#xff1a…

VMware Workstation及CentOS-7虚机安装

创建新的虚机: 选择安装软件(这里选的是桌面版,也可以根据实际情况进行选择) 等待检查软件依赖关系 选择安装位置,自主配置分区 ​​​​​​​ 创建一个普通用户 安装完成后重启 点击完成配置,进入登陆界面…

怎么进行流程图制作?用这个工具制作很方便

怎么进行流程图制作?流程图是一种非常有用的工具,可以帮助我们更好地理解和展示各种复杂的业务流程和工作流程。它可以将复杂的过程简化为易于理解的图形和文本,使得人们更容易理解和跟踪整个流程。因此,制作流程图是在日常工作中…

拆解与重构:慕云游首页组件化设计

目录 前言1 项目准备1.1 创建项目目录1.2 搭建项目开发环境 2 项目组件化2.1 在当前环境启动原有项目2.2 顶部组件2.3 幻灯片组件2.3.1 功能实现2.3.2 加载中组件2.3.3 结构和样式2.3.4 使用Ajax获取数据 2.4 机酒自由行组件2.5 拆分余下的css文件 3 项目完善4 源码 前言 在现代…

如何使Python Docker镜像安全、快速、小巧

一、说明 在微服务领域,拥有安全、高效和紧凑的 Docker 映像对于成功部署至关重要。本博客将探讨有助于构建此类映像的关键因素,包括不以 root 用户身份运行映像的重要性、在构建映像时更新和升级包、在编写 Dockerfile 指令时考虑 Docker 的层架构&…

岩土工程仪器多通道振弦传感器信号转换器应用于桥梁安全监测

岩土工程仪器多通道振弦传感器信号转换器应用于桥梁安全监测 桥梁作为交通运输的重要节点,其安全性一直备受关注。不同于其他建筑物,桥梁所处的环境复杂多变,同时,其所需承受的负荷也相对较大,这就需要对桥梁的安全进…

Windows 安装 pandoc 将 jupyter 导出 pdf 文件

Windows 安装 pandoc 将 jupyter 导出 pdf 文件 1. 下载 pandoc 安装文件2. 安装 pandoc3. 安装 nbconvert4. 使用 pandoc 1. 下载 pandoc 安装文件 访问 https://github.com/jgm/pandoc/releases,下载最新版安装文件,例如,3.1.6.1 版&#…

常见分布式ID解决方案总结:数据库、算法、开源组件

常见分布式ID解决方案总结 分布式ID分布式ID方案之数据库数据库主键自增数据库号段模式Redis自增MongoDB 分布式ID方案之算法UUIDSnowflake(雪花算法) 雪花算法的使用IdWorker工具类配置分布式ID生成器 分布式ID方案之开源组件uid- generator(百度)Tinyid(滴滴&…

基于Java的体育网站的设计与实现(论文+源码)_kaic

基于Java的体育网站的设计与实现 摘 要:在网络应用的迅速发展与科技的不断进步的现代环境下,人们生活节奏越来越快,娱乐方式也多种多样,各种软件应用,各种娱乐,购物网站已经成为必不可少的伴随品&#xff…

《24海南大学835软件工程考研经验贴》

1.经验之谈 首先,我是一个二战的考生,一战给我带来的经验有几点。第一,数学、专业课这两门越早复习越好,越拖到后面你就会发现来不及了,这学不完,那学不完的。第二、我认为是比较关键的一点,一定…

Idea创建maven管理的web项目

如果你想在项目中添加一个传统的 src 目录来存放源代码,可以按照以下步骤操作: 1. 在项目视图中,右键单击项目名称,选择 “New” -> “Directory”。 2. 在弹出的对话框中,输入目录名称为 “src”,然后…

使用ffmpeg将m4a及wav等文件转换为MP3格式

要使用ffmpeg将m4a及wav等文件转换为MP3格式,您可以按照以下步骤进行操作: 安装 ffmpeg 确保您已经安装了ffmpeg软件。如果没有安装,请访问ffmpeg的官方网站https://ffmpeg.org/ 并按照说明进行安装。 Win10 / Win11 可以通过 winget 命令…

Vue自定义指令使用

本篇文章讲述使用Vue自定义指令,并在项目中完成相应功能。 在平常Vue脚手架项目中,使用到 自定义指令较少,一般都是使用的自带指令,比如 v-show 、v-if 、 v-for 、 v-bind 之类的。这些已经能够满足大多数项目使用。更多的可能也…

蚁剑antSword-maste下载-安装-使用-一句话木马

下载 https://github.com/AntSwordProject/antSword 一句话木马 hack.php脚本 <?php eval($_POST[attack]);?> 安装 1、安装完成后启动 2、初始化&#xff0c;选择有源码的目录 3、连接

SpringMVC的架构有什么优势?——视图与模型(二)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

c语言每日一练(2)

前言&#xff1a; 每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。每日一练系列会持续更新&#xff0c;暑假时三天之内必有一更&#xff0c;到了开学之后&#xff0c;将看学业情…

leetcode 63. 不同路径 II

2023.8.9 这题是不同路径I的升级版&#xff0c;在路径上增加了障碍物&#xff0c;有障碍物的地方无法通过。 我的思路依然还是使用动态规划&#xff0c;dp[i][j]的含义依然是到&#xff08;i&#xff0c;j&#xff09;这个位置的路径个数。只需要在dp数组中将有障碍物的地方赋为…

js案例:1.简单计算器

目录 一.效果图 二.实现思路 整体思路 ​ 1.关键是dom操作 ​ 2.设置点击事件 3.数据类型的隐式转换和赋值 三.完整代码 一.效果图 二.实现思路 整体思路 1.关键是dom操作 通过 document.getElementById(id) 获取html中的dom元素 每一个html标签都是一个对象&…

CANoe通过Frame Histogram窗口统计报文周期(方便快捷)

文章目录 效果展示1.插入Frame Histogram窗口2.Activate3.运行CANoe&#xff0c;停止后查看write窗口 效果展示 统计报文周期信息输出在write窗口。 1.插入Frame Histogram窗口 2.Activate 3.运行CANoe&#xff0c;停止后查看write窗口 统计报文周期信息输出在write窗口。

Pytorch深度学习-----神经网络模型的保存与加载(VGG16模型)

系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用&#xff08;ToTensor&#xff0c;Normalize&#xff0c;Resize &#xff0c;Co…