最近看了潇晨大佬的源码解读,写的很不错,下面以潇晨的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树的结构为
从图中可以看出,通过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构建完成
该过程的函数调用关系如图
接下来更改FiberRoot和RootFiber的指针指向,此时两个对象的关系如图
Tips
如发现文章内的错误或有疑问,可联系邮箱maplesyrupr@outlook.com