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

用于调试和内部记录。

相关推荐
『 时光荏苒 』13 分钟前
网页变成PDF下载到本地
前端·javascript·pdf·网页下载成
亿元程序员20 分钟前
逃离鸭科夫5人2周1个亿,我们可以做一个鸡科夫吗?
前端
十一.36639 分钟前
37-38 for循环
前端·javascript·html
波诺波39 分钟前
环境管理器
linux·前端·python
San30.1 小时前
深入理解浏览器渲染流程:从HTML/CSS到像素的奇妙旅程
前端·css·html
IT_陈寒1 小时前
5个Python 3.12新特性让你的代码效率提升50%,第3个太实用了!
前端·人工智能·后端
周杰伦_Jay1 小时前
【Python Web开源框架】Django/Flask/FastAPI/Tornado/Pyramid
前端·python·开源
艾小码1 小时前
为什么你的JavaScript代码总是出bug?这5个隐藏陷阱太坑了!
前端·javascript
辻戋3 小时前
从零实现React Scheduler调度器
前端·react.js·前端框架
徐同保3 小时前
使用yarn@4.6.0装包,项目是react+vite搭建的,项目无法启动,报错:
前端·react.js·前端框架