前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React源码阅读(二):Fiber结构实现

React源码阅读(二):Fiber结构实现

作者头像
源心锁
发布2022-08-12 11:34:42
2810
发布2022-08-12 11:34:42
举报
文章被收录于专栏:前端魔法指南

首先,我们本次的切入文件如下

代码语言:javascript
复制
packages/react-reconciler/src/ReactFiber.new.js

虚拟DOM;我们都知道虚拟DOM,但是React中它其实有个正式的称呼Fiber

目前我了解到的,在React15及以前,Reconciler采用递归的方式创建虚拟DOM,递归过程是不能中断的。如果组件树的层级很深,递归会占用线程很多时间,造成卡顿。

而在React16之后,Fiber架构使得更新被转变为了异步的可中断更新

阅读起来~FiberNode

从1-112行似乎都和正文没有太大关系,更多的是各种导入以及环境变量的设定,我们从114行开始

函数FiberNode的参数共四个,由于文件上边包含了@flow,所以这里可以使用类型注解。

同时结合下边大量this.xxx,显然这是一个构造函数,定义了Fiber节点的属性值,下边的函数里我删掉了一段优化性能以及另一方便测试使用的代码

代码语言:javascript
复制
function FiberNode(
  tag: WorkTag,
  pendingProps: mixed,
  key: null | string,
  mode: TypeOfMode,
) {
  // 实例变量,从字面意思也应该可以看出这里保存了tag、key、type、state类似这样的有很强实际意义的属性
  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;
}

那么我试着按照官方空格分段一点点看看,第一部分还是比较容易理解的

实例数据/静态数据

代码语言:javascript
复制
// 实例变量,从字面意思也应该可以看出这里保存了tag、key、type、state类似这样的有很强实际意义的属性
  this.tag = tag;
  this.key = key;
  this.elementType = null;
  this.type = null;
  this.stateNode = null;

这一部分,保存了组件的相关信息,其中各个属性的含义又分别代表:

  • tag 注意到tag在下边很多地方都能看到,而通过注解我们知道这是一个WorkTag类型(所以知道TypeScript为什么这么受欢迎了嘛,一眼就知道下一步看哪里) 那么可以看到

代码语言:javascript
复制
export type WorkTag =
  | 0
  | 1
  ...
  | 23
  | 24;

export const FunctionComponent = 0;
//函数式组件
export const ClassComponent = 1;
//类组件
export const IndeterminateComponent = 2;
...
export const LegacyHiddenComponent = 23;
export const CacheComponent = 24;

嗷,我们似乎一下子看到了不得了的东西。其实这里是意思是,0对应函数式组件、1对应类组件、2对应不确定组件(我不知道这个噶)......这样往下去对应。这里包含的显然是React的组件类型,于是我们本次阅读源码的收获之一到手

TODO: React 的25种组件类型

  • key 略,和你想的那个key就是一个意思
  • elementType 我们从本段其实看不到太多,往下翻。

疑似和type没有太大差别......嗯不太理解了查查资料

  • type 对于 FunctionComponent,指函数本身,对于ClassComponent,指class,对于HostComponent,指DOM节点tagName
  • stateNode 这个好说,这里代表的的是真实节点

return、child、sibling、index

这几个属性用于生成Fiber Tree结构

代码语言:javascript
复制
// 指向上一级级Fiber节点
this.return = null;
// 指向下一级Fiber节点
this.child = null;
// 指向右边第一个兄弟Fiber节点
this.sibling = null;
//同级节点中自己是第几个
this.index=0;

而Fiber Tree结构我们举个例子伐

代码语言:javascript
复制
function App(){
    return (
        <div>
        	<p>Hello</p>
            <div>
            	<span>Fiber</span>
            </div>
        </div>)
}

最终要生成这么一颗Fiber树,而这其实就对应我们所说的虚拟DOM树,首先列出节点

我还没有很清楚DOM和Fiber之间的详细关系,暂时不加入关系图,剩下的连接起来。如下:

BUT......为什么不用parent来命名return

更多数据*from kasong

代码语言:javascript
复制
// 看起来颇为爆炸,保存本次更新造成的状态改变相关信息
this.pendingProps = pendingProps;
this.memoizedProps = null;
this.updateQueue = null;
this.memoizedState = null;
this.dependencies = null;

this.mode = mode;

// 保存本次更新会造成的DOM操作
this.effectTag = NoEffect;
this.nextEffect = null;

this.firstEffect = null;
this.lastEffect = null;

// 调度优先级相关
this.lanes = NoLanes;
this.childLanes = NoLanes;

这一块有较多关联,包括更新过程中的一些参数、调度优先级,可以先从字面意义理解;

从pendingProps、memoizeProps的字面意思,这些都是和父组件传入的props相关的参数,保存的也是对应pending、memoized这些状态下的props

类似的,后边我们才会具体接触到这些参数

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-11-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 阅读起来~FiberNode
    • 实例数据/静态数据
      • return、child、sibling、index
        • 更多数据*from kasong
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档