RootFiber和FiberRoot

2,509 阅读1分钟

Untitled.png

首次执行ReactDOM.render会创建fiberRootNode(源码中叫fiberRoot)和rootFiber

fiberRootNode

fiberRootNode是整个应用的根节点,绑定在真实DOM节点的_reactRootContainer属性上,当对一个元素重复调用ReactDOM.renderfiberRootNode不会改变。

//FiberRoot 
const rootFiber= new FiberNode();
const fiberRootNode={
        current: rootFiber,
        containerInfo: containerInfo,
        context: null,
        pendingContext: null,
        expirationTime: NoWork,
	.......
 }
rootFiber.stateNode=fiberRootNode

rootFiber

rootFiber<App/>所在组件树的根节点,rootFiber在每次重新渲染的时候会重新构建。

diff算法的作用对象也是rootFiber树和当前虚拟dom树。


// Instance
  this.tag = 3; // 不同的组件类型
  this.key = null; // react element 的 key
  this.elementType = null; // react element 的 type
  this.type = null; // 异步组件resolved之后返回的内容,一般是`function`或者`class`
  this.stateNode = null; // 跟当前Fiber相关本地状态(比如浏览器环境就是DOM节点)
  
// Fiber
  this.return = null; // 指向他在Fiber节点树中的`parent`,用来在处理完这个节点之后向上返回
  this.child = null; // 指向自己的第一个子节点
  this.sibling = null; // 兄弟节点的return指向同一个父节点
  
  this.index = 0;
  this.ref = null; // ref
  this.pendingProps = pendingProps; // 新的 props
  this.memoizedProps = null; // 旧的 props
  this.memoizedState = null; // 新旧 state  

  this.updateQueue = null; // 该Fiber对应的组件产生的Update会存放在这个队列里面
  
  this.dependencies = null;
  this.mode = mode; // Effects 表示这个子树是否默认是异步渲染的

//effect
  this.effectTag = NoEffect; // 用来记录Side Effect
  this.nextEffect = null; // 用来快速查找下一个side effect
  this.firstEffect = null; // 第一个side effect
  this.lastEffect = null; // 最后一个side effect
  
  this.alternate = null; // `current <==> workInProgress` 在渲染完成之后他们会交换位置,类似于备份,方便重用

为什么要区分

在应用中当多次调用ReactDOM.render渲染不同的组件树的时候,它们会拥有不同的rootFiber,但整个应用的根节点只有一个fiberRootNode

fiberRootNodecurrent会指向当前页面上已渲染内容对应Fiber树,即current Fiber树。

fiberRootNode.current = rootFiber;

参考资料