【React源码学习】0 Fiber根节点的构建


最近看了潇晨大佬的源码解读,写的很不错,下面以潇晨的blog为基础整理以下学习React源码的相关内容。

本篇blog主要关注Fiber树根节点的构建过程

从浏览器中可以看到这一部分函数的调用关系

函数调用关系

Fiber树的基本概念

React通过Fiber将真实的DOM结构映射到内存中,每一个Fiber可以看作是一个DOM节点,React会在内存中构建两个Fiber树,一个是根据当前DOM树构建的current Fiber,另一个是正在构建的workInProgress Fiber

以下方代码为例,可视化两个Fiber树的关系

function App() {
  return (
      <h1>
        <p>count</p> maple
      </h1>
  )
}

ReactDOM.render(<App />, document.getElementById("root"));

则该Fiber树的结构为

Fiber树结构

从图中可以看出,通过child和return指针确定Fiber的父子关系,通过sibling指针连接兄弟节点,构建一个Fiber树时会采用类似DFS的方式,先构建其子节点,子节点构建结束后构建兄弟节点。

Fiber树根节点的首次构建

该过程调用的函数如下

function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {
  var root = new FiberRootNode(containerInfo, tag, hydrate);
  var uninitializedFiber = createHostRootFiber(tag);
  root.current = uninitializedFiber;
  uninitializedFiber.stateNode = root;
  initializeUpdateQueue(uninitializedFiber);
  return root;
}

FiberRoot是一个特殊的对象,在内存中只存在一个,构建Fiber树时先构建FiberRoot

1 首先调用FiberRootNode构建一个FiberRoot对象,该构造函数会设置Fiber相关属性,例如eventTimes,context等

2 接下来构建RootFiber,RootFiber同样是一个特殊对象,双缓存中的每个Fiber树都有一个RootFiber

在createHostRootFiber内调用createFiber,createFiber的代码如下(函数套娃开始了)

var createFiber = function (tag, pendingProps, key, mode) {
  return new FiberNode(tag, pendingProps, key, mode);
};

createFiber内调用FiberNode,该函数会根据传入的tag(Lagacy模式下是0,Concurrent模式下是1),props,key等参数构建一个Fiber对象,具体的代码可以在ReactFiber.old.js中看到。此时FiberRoot和RootFiber构建完成

该过程的函数调用关系如图

createFiberRoot内部函数调用关系

接下来更改FiberRoot和RootFiber的指针指向,此时两个对象的关系如图

FiberRoot和RootFiber关系

Tips

如发现文章内的错误或有疑问,可联系邮箱maplesyrupr@outlook.com


Author: Maple
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source Maple !
  TOC