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

React16源码: React中FiberRoot的源码实现

关于 FiberRoot


1 )概述

  • ReactDOM.render 过程当中,创建了一个 ReactRoot的对象
  • 这个 ReactRoot 对象最主要承担了创建 FiberRoot 对象
  • 这个对象它非常重要,在后期整个应用调度过程当中都会跟它有关
  • 关于 FiberRoot 对象
    • A. 它是整个应用的起点
    • B. 它包含了ReactDOM.render 传进去的第二个参数
      • 就是一个dom节点,我们应用挂载的那个节点相关的一些信息
    • C. 它还记录着整个应用更新过程当中的各种信息
      • 应用更新过程当中,会涉及到各种各样的东西
    • 比如,各种不同类型的 expirationTime,还有异步调度任务的callback这些东
    • 都会记录在这个 FiberRoot 上面

2 ) 相关源码

  • 在 ReactRoot 构造函数中基于 DOMRenderer.createContainer 创建了 FiberRoot 对象
    // ReactDOM.js
    function ReactRoot(container: Container,isConcurrent: boolean,hydrate: boolean,
    ) {const root = DOMRenderer.createContainer(container, isConcurrent, hydrate);this._internalRoot = root;
    }// ReactFiberReconciler.js
    export function createContainer(containerInfo: Container,isConcurrent: boolean,hydrate: boolean,
    ): OpaqueRoot {return createFiberRoot(containerInfo, isConcurrent, hydrate);
    }// ReactFiberRoot.js
    export function createFiberRoot(containerInfo: any,isConcurrent: boolean,hydrate: boolean,
    ): FiberRoot {// Cyclic construction. This cheats the type system right now because// stateNode is any.const uninitializedFiber = createHostRootFiber(isConcurrent);let root;if (enableSchedulerTracing) {root = ({// root 节点对应的Fiber对象(root节点也是可能会更新的),是 Root Fiber// 后续整个应用都会有一个Fiber的树结构,任何一个ReactElement的节点都会对应一个Fiber对象// ReactElement是一个树结构, Fiber对象也会有一个树结构// 它是Fiber树结构的顶点current: uninitializedFiber,containerInfo: containerInfo, // ReactDOM.render 传进去的第二个参数 dom 节点pendingChildren: null, // 只有在持久更新中会用到,也就是不支持增量更新的平台,react-dom中不会被用到,在server-render中会被用到,因为它需要输出很多字符串类型的html节点// 以下的优先级是用来区分// 1 ) 没有提交(committed)的任务// 2 ) 没有提交的挂起任务// 3 ) 没有提交的可能被挂起的任务// 最老和最新的不确定是否会挂起的优先级 (所有任务进来一开始都是这个状态)earliestPendingTime: NoWork,latestPendingTime: NoWork,// 最老和最新的在提交的时候被挂起的任务earliestSuspendedTime: NoWork,latestSuspendedTime: NoWork,// 最新的通过一个promise被resolve并且可以重新尝试的优先级latestPingedTime: NoWork,didError: false, // 在renderRoot 出现无法处理的错误时会被设置为 truependingCommitExpirationTime: NoWork, // 正在等待提交的任务的 expirationTime// 已经完成的任务的FiberRoot对象,如果你只有一个Root, 它永远只可能是这个Root对应的Fiber, 或者是 null// 在 commit 阶段只会处理这个值对应的任务// 用于记录在一次更新渲染过程当中完成了的更新任务, 因为整棵树中会存在各种不同的更新任务// 每一次更新会渲染优先级最高的任务,优先级最高的任务渲染完成之后就是一个 finishedWork,标记在应用的Root上面// 更新完了要把应用输出到Dom节点上面,输出的过程就是读取的这个 finishedWork 值finishedWork: null,// 在任务被挂起的时候通过setTimeout设置的返回内容// 用来下一次如果有新的任务挂起时清理还没触发的timeout// 例如:Suspense 组件功能, 在render function 中 throw 一个 Promise, 之后任务会被挂起// 挂起之后可以渲染 Suspense 组件的 fallback, 等到 Promise resolve之后// 它就会把 resolve之后的数据显示出来,这时候就会有一个 timeoutHandle来帮助我们记录超时的情况的// 这个会在后续的更新流程中timeoutHandle: noTimeout,// 顶层 context 对象, 只有主动调用 `renderSubtreeIntoContainer` 时才会有用// `renderSubtreeIntoContainer` 这个API出场率非常低,不常用context: null,pendingContext: null,// 用来确定第一次渲染的时候是否需要融合// 应用是否要跟原来存在的dom节点进行合并hydrate,// 当前root上剩余的过期时间// 用来标记这一次更新渲染的时候要执行的是哪个优先级的任务// 应用更新过程中会遍历到每一个节点,每个节点如果有更新,会有自己的一个 ExpirationTime// root 上记录整个应用当中优先级最高的 ExpirationTime // 在更新的过程中,会根据这个nextExpirationTimeToWorkOn变量去进行一个更新// 就是说如果遍历到某个节点,发现自己的 ExpirationTime 比这个值要大,则说明它优先级要低// 且还轮不到它来更新,就可以进行一个跳过,这就是这个变量的用处nextExpirationTimeToWorkOn: NoWork,// 当前更新对应的过期时间// 用在我们调度的过程当中, 和 上面的 nextExpirationTimeToWorkOn 大部分时间都是相同的// 但是也会有一定的区别expirationTime: NoWork,// 暂时不管这个firstBatch: null,// root之间关联的链表结构// 这个属性是单向链表的属性// 比如,dom节点有 root1 和 root2 两个div// ReactDOM.render 把一个应用渲染在 root1 中,把另一个应用渲染在 root2 中// 这时候会存在两个root, 它们在react中会用 nextScheduledRoot 这个属性进行一个串联// 在整个react更新调度过程中,在这个链表中去找哪个root对应的优先级最高,执行那个root的更新// 一个root里面又会有不同优先级的任务在里面,它整体的过程是非常的复杂nextScheduledRoot: null,interactionThreadID: unstable_getThreadID(),memoizedInteractions: new Set(),pendingInteractionMap: new Map(),}: FiberRoot);} else {root = ({current: uninitializedFiber,containerInfo: containerInfo,pendingChildren: null,earliestPendingTime: NoWork,latestPendingTime: NoWork,earliestSuspendedTime: NoWork,latestSuspendedTime: NoWork,latestPingedTime: NoWork,didError: false,pendingCommitExpirationTime: NoWork,finishedWork: null,timeoutHandle: noTimeout,context: null,pendingContext: null,hydrate,nextExpirationTimeToWorkOn: NoWork,expirationTime: NoWork,firstBatch: null,nextScheduledRoot: null,}: BaseFiberRootProperties);}uninitializedFiber.stateNode = root;// The reason for the way the Flow types are structured in this file,// Is to avoid needing :any casts everywhere interaction tracing fields are used.// Unfortunately that requires an :any cast for non-interaction tracing capable builds.// $FlowFixMe Remove this :any cast and replace it with something better.return ((root: any): FiberRoot);
    }
    

3 )相关解析

  • 注意,上面的各种 Time 非常重要,在后续任务调度的过程中,用来记录更新所涉及的时间的
    • js 在浏览器中是单线程的, 我们的应用又是一个树形结构
    • 如何去区分不同优先级的任务,就要用各种不同的变量去标记
    • 这几个变量就是用于去标识不同优先级的任务的
  • 其他字段参考上述源码中注释的释义

相关文章:

React16源码: React中FiberRoot的源码实现

关于 FiberRoot 1 )概述 在 ReactDOM.render 过程当中,创建了一个 ReactRoot的对象这个 ReactRoot 对象最主要承担了创建 FiberRoot 对象这个对象它非常重要,在后期整个应用调度过程当中都会跟它有关关于 FiberRoot 对象 A. 它是整个应用的起…...

Linux第24步_安装windows下的VisualStudioCode软件

Visual Stuio Code是一个编辑器,简称 为 VSCode,它是微软出的一款免费编辑器。 VSCode有 Windows、 Linux和 macOS三个版本的,是一个跨平台的编辑器。VSCodeUserSetup-x64-1.50.1是Windows系统中的VSCode软件,而“code_1.50.1-160…...

Spring 注解 和SpringMVC注解

Spring和Spring MVC是两个紧密相关但又不同的框架,它们都使用一系列注解来简化开发。以下是Spring和Spring MVC中一些常用的注解: ### Spring 注解: 1. **Component:** - 用于将类标记为Spring容器中的组件,由Spr…...

iOS rootless无根越狱解决方案

据游戏工委数据统计,2023年国内游戏市场实际销售收入与用户规模双双创下新高,游戏普遍采用多端并发方式,成为收入增长的主因之一。 中国市场实际销售收入及增长率丨数据来源:游戏工委 多端互通既是机遇,也是挑战。从游…...

文件管理小技巧:如何高效整理多种格式的图片,图片分类的方法

随着数字时代的到来,每天都会处理到大量的图片,从个人照片到工作相关的图像资料。如何高效地整理多种格式的图片,常常让人感到困扰。下面看下云炫文件管理器如何对图片分类的方法。 jpg图片、png图片、tiff图片未归类前的缩略图。 jpg图片、…...

【c++】入门4

内联函数声明和定义不能分开 inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址 了,链接就会找不到。 auto关键字 随着程序越来越复杂,程序中用到的类型也越来越复杂,经常体现在&…...

使用Web自动化测试工具显著好处

随着互联网技术的飞速发展,Web应用程序在企业中的重要性不断上升。为了确保Web应用程序的质量和稳定性,许多企业转向了Web自动化测试工具。下面是使用Web自动化测试工具的一些显著好处: 1. 提高测试覆盖率 Web自动化测试工具可以模拟用户与We…...

【性能】【算法】for循环,性能提高

目录 ■提高性能的方法 ・原理 1.1.java处理中,计算阶乘,为什么展开循环可以提高效率 1.2.从cpu的流水线角度,再说明一下 1.3.介绍一下 cup的指令流水线 ■实际运用 1.求和 代码 结果 2.求阶乘 (性能提高效果明显&…...

【入门】字符串对比(UPC)

题目描述 给定两个仅由大写字母或小写字母组成的字符串(长度介于1到100之间),它们之间的关系是以下4种情况之一: 1:两个字符串长度不等。比如 Beijing 和 Hebei 2:两个字符串不仅长度相等,而且相应位置上的字符完…...

thinkphp美容SPA管理系统源码带文字安装教程

thinkphp美容SPA管理系统源码带文字安装教程 运行环境 服务器宝塔面板 PHP 7.0 Mysql 5.5及以上版本 Linux Centos7以上 基于thinkphp3.23B-JUI1.2开发,权限运用了Auth类认证,权限可以细分到每个功能, 增删改查功能一应俱全,整合了…...

apache共享目录文件配置

httpd配置文件路径 /etc/httpd/conf/httpd.conf 配置单个节点 httpd中原本有一个配置 <Directory "/var/www">AllowOverride None# Allow open access:Require all granted </Directory># Further relax access to the default document root: <D…...

kotlin take 和 drop

kotlin take的作用 从头开始获取指定数量的元素 val numbers listOf("one", "two", "three", "four", "five", "six") // 取集合的4个集合 Log.d("take", numbers.take(3).toString()) // 打印结果[…...

SQL-DML增删改

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现错误&am…...

雷达信号处理——恒虚警检测(CFAR)

雷达信号处理的流程 雷达信号处理的一般流程&#xff1a;ADC数据——1D-FFT——2D-FFT——CFAR检测——测距、测速、测角。 雷达目标检测 首先要搞清楚什么是检测&#xff0c;检测就是判断有无。雷达在探测的时候&#xff0c;会出现很多峰值&#xff0c;这些峰值有可能是目标…...

k8s的yaml文件中的kind类型都有哪些?(详述版Part1/2)

目录 综述 分块详述 1、Pod 2、Deployment 3、Service 4、DaemonSet 5、ReplicaSet 6、ServiceAccount 7、PodDisruptionBudget 8、PersistentVolumeClaim 9、PersistentVolume 10、Job 11、CronJob 12、StatefulSet 综述 通过yaml文件中的kind可以大致了解kube…...

企业培训系统源码:构建智能、可扩展的学习平台

企业培训系统在现代企业中扮演着至关重要的角色。本文将通过深度解析企业培训系统的源码&#xff0c;介绍如何构建一个智能、可扩展的学习平台&#xff0c;涉及关键技术和代码实例。 1. 技术栈选择与项目初始化 在构建企业培训系统之前&#xff0c;选择适当的技术栈是至关重…...

设计模式—行为型模式之状态模式

设计模式—行为型模式之状态模式 状态&#xff08;State&#xff09;模式&#xff1a;对有状态的对象&#xff0c;把复杂的“判断逻辑”提取到不同的状态对象中&#xff0c;允许状态对象在其内部状态发生改变时改变其行为。 状态模式包含以下主要角色&#xff1a; 环境类&am…...

Linux习题3

解析&#xff1a; grep&#xff1a;查找文件内的内容 gzip&#xff1a;压缩文件&#xff0c;文件经压缩后会增加 gz&#xff1a;扩展名 find&#xff1a;在指定目录下查找文件 解析&#xff1a; A hosts文件是Linux系统上一个负责ip地址与域名快速解析的文件&#xff0c;以…...

SpringBoot+策略模式实现多种文件存储模式

一、策略模式 背景 针对某种业务可能存在多种实现方式&#xff1b;传统方式是通过传统if…else…或者switch代码判断&#xff1b; 弊端&#xff1a; 代码可读性差扩展性差难以维护 策略模式简介 策略模式是一种行为型模式&#xff0c;它将对象和行为分开&#xff0c;将行…...

细说DMD芯片信号-DLP3

1&#xff0c; Block diagram 2. 信号介绍 2.1, LS interface&#xff1a; LD_Data_P/N(i), LD_CLK_P/N(i), LS_RDATA_A_BIST(O) 2.2, 视频信号: HSSI(High speed serial interface) High speed Differential Data pair lan A0~7 P/N, High speed Differential Clock A High…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...

【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权

摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题&#xff1a;安全。文章将详细阐述认证&#xff08;Authentication) 与授权&#xff08;Authorization的核心概念&#xff0c;对比传统 Session-Cookie 与现代 JWT&#xff08;JS…...

aardio 自动识别验证码输入

技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”&#xff0c;于是尝试整合图像识别与网页自动化技术&#xff0c;完成了这套模拟登录流程。核心思路是&#xff1a;截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...