FiberNode结构解析

FiberNode结构解析

FiberNode(也称为 Fiber 节点)是 React Fiber 架构中的核心概念之一,用于表示组件的层级结构和渲染过程中的任务。

javascript 复制代码
function FiberNode(tag, pendingProps, key, mode) {
  // Instance
  this.tag = tag;
  this.key = key;
  this.elementType = null;
  this.type = null;
  this.stateNode = null; // Fiber
  this.return = null;
  this.child = null;
  this.sibling = null;
  this.index = 0;
  this.ref = null;
  this.pendingProps = pendingProps;
  this.memoizedProps = null;
  this.updateQueue = null;
  this.memoizedState = null;
  this.dependencies = null;
  this.mode = mode; // Effects

  this.flags = NoFlags;
  this.subtreeFlags = NoFlags;
  this.deletions = null;
  this.lanes = NoLanes;
  this.childLanes = NoLanes;
  this.alternate = null;

  {
    // Note: The following is done to avoid a v8 performance cliff.
    //
    // Initializing the fields below to smis and later updating them with
    // double values will cause Fibers to end up having separate shapes.
    // This behavior/bug has something to do with Object.preventExtension().
    // Fortunately this only impacts DEV builds.
    // Unfortunately it makes React unusably slow for some applications.
    // To work around this, initialize the fields below with doubles.
    //
    // Learn more about this here:
    // https://github.com/facebook/react/issues/14365
    // https://bugs.chromium.org/p/v8/issues/detail?id=8538
    this.actualDuration = Number.NaN;
    this.actualStartTime = Number.NaN;
    this.selfBaseDuration = Number.NaN;
    this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
    // This won't trigger the performance cliff mentioned above,
    // and it simplifies other profiler code (including DevTools).

    this.actualDuration = 0;
    this.actualStartTime = -1;
    this.selfBaseDuration = 0;
    this.treeBaseDuration = 0;
  }

  {
    // This isn't directly used but is handy for debugging internals:
    this._debugSource = null;
    this._debugOwner = null;
    this._debugNeedsRemount = false;
    this._debugHookTypes = null;

    if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
      Object.preventExtensions(this);
    }
  }
}
tag

表示 FiberNode 的类型,可以是 HostComponent、ClassComponent、FunctionComponent 等。

key

表示组件的唯一标识符,用于在列表渲染中进行元素的重用。

elementType

表示组件元素的类型。大部分情况同type,某些情况不同,比如FunctionComponent使用React.memo包裹。

type

type 属性表示 FiberNode 对应的组件类型,可以是字符串(原生组件)或函数/类(自定义组件)。对于 FunctionComponent,指函数本身,对于ClassComponent,指class,对于HostComponent,指DOM节点tagName。

stateNode

每个 FiberNode 包含一个 stateNode 属性,它指向组件实例。stateNode 可以是一个 DOM 元素(对于原生组件),也可以是一个类实例(对于自定义组件)。

​ FiberNode 使用链表结构来表示组件的层级关系

return

return 指向父节点。

child

child 属性指向第一个子节点。

sibling

sibling 属性指向下一个兄弟节点。

例子:
react 复制代码
function App() {
  return (
    <div>
      i am
      <span>SongShao</span>
    </div>
  )
}

对应的Fiber树结构

sh 复制代码
		    App
		    ||
	  child || return
			||
    --------div ----------------
	        ||  			 ||
	  child || return  child || return 
            ||				 ||
           i am ----------- span
                  sibling    ||
              		   child || return
              		 	     ||
              		      SongShao
       

这里需要提一下,为什么父级指针叫做return而不是parent或者father呢?因为作为一个工作单元,return指节点执完completeWork(本章后面会介绍)后会返回的下一个节点。子Fiber节点及其兄弟节点完成工作后会返回其父级节点,所以用return指代父级节点。

index

在父节点中的索引位置。

ref

用于引用组件。

pendingProps

组件的待处理属性。

memoizedProps 和 memoizedState

这些属性保存了组件的当前状态(props 和 state)。在渲染过程中,React 使用 memoizedProps 和 memoizedState 保存组件的最新状态,并通过比较前后两次状态的差异,确定是否需要更新组件。

updateQueue

用于存储组件的更新队列。

dependencies

表示组件的依赖项。

mode

表示渲染模式。

flags 和 subtreeFlags

表示 FiberNode 的状态标志。

deletions

表示待删除的节点。

lanes 和 childLanes

表示调度的优先级。

alternate

alternate 属性指向 FiberNode 的替代节点。在渲染过程中,React 会创建两个 FiberNode,一个表示当前渲染状态,另一个表示下一次渲染状态。通过 alternate 属性,React 在两个状态之间进行比较,找出需要更新的节点。

actualDuration、actualStartTime、selfBaseDuration、treeBaseDuration

用于记录组件的实际渲染时间和基准时间。

__debugSource、__debugOwner、__debugNeedsRemount、__debugHookTypes

用于调试和内部记录。

相关推荐
我要洋人死25 分钟前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人37 分钟前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人38 分钟前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR43 分钟前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai1 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
逐·風6 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#