react解析: render的FiberRoot(三)

感谢 yck: 剖析 React 源码解析,本篇文章是在读完他的文章的基础上,将他的文章进行拆解和加工,加入我自己的一下理解和例子,便于大家理解。觉得yck写的真的很棒 。React 版本为 16.8.6,关于源码的阅读,可以移步到yck react源码解析

本文永久有效链接: react解析 render的FiberRoot(三)

下面将会说到 ReactDOM.render 在ReactDOM中的调用流程,实际就是分析下面代码:

ReactDOM.render(<APP />, document.getElementById('app'))

实际代码:

ReactDOM.render(React.createElement(APP, null), document.getElementById('app'));

render 函数

yck: ReactDOM 源码 702行 render

ReactDOM.render实际调用的就是下面的代码

render(
element: React$Element<any>,
container: DOMContainer,
callback: ?Function,
) {
// 注意下 forceHydrate 参数,为 true 时是服务端渲染
// 客户端调用 render 函数的话这个值永远为 false
return legacyRenderSubtreeIntoContainer(
null,
element,
container,
false,
callback,
);
}

render函数中的参数element是 传入的组件,containerDOM节点容器,callback是回调函数。ReactDOM.render文档

legacyRenderSubtreeIntoContainer 函数

yck: ReactDOM 源码 554行 legacyRenderSubtreeIntoContainer

function legacyRenderSubtreeIntoContainer(
parentComponent: ?React$Component<any, any>,
children: ReactNodeList,
container: DOMContainer,
forceHydrate: boolean,
callback: ?Function,
) {
// 初始化时,container 肯定没有 _reactRootContainer属性
let root: Root = (container._reactRootContainer: any);
if (!root) {
root = container._reactRootContainer = legacyCreateRootFromDOMContainer(
container, // DOM容器节点
forceHydrate, // 为false
);
// 暂时只说root不存在时,reactRoot的创建
}
}

container表示DOM元素节点容器, 在上面的代码中会创建一个ReactRoot,然后将它挂载在container容器上, container._reactRootContainer就是挂载的ReactRoot属性。

// 查看_reactRootContainer
document.getElementById('app')._reactRootContainer

创建FiberRoot核心函数

yck: ReactDOM 源码 504行 legacyCreateRootFromDOMContainer

function legacyCreateRootFromDOMContainer(
container: DOMContainer,
forceHydrate: boolean,
): Root {
const isConcurrent = false;
// 调用ReactRoot函数 创建ReactRoot, shouldHydrate是SSR相关,不用管
return new ReactRoot(container, isConcurrent, shouldHydrate);
}

yck: ReactDOM 源码 368行 ReactRoot

function ReactRoot(
container: DOMContainer,
isConcurrent: boolean,
hydrate: boolean,
) {
// 这个 root 指的是 FiberRoot
const root = createContainer(container, isConcurrent, hydrate);
this._internalRoot = root;
}

调用createContainer 创建FiberRoot,下面我们将会说到FiberRoot 对象

FiberRoot

yck: ReactDOM 源码 368行 createContainer

export function createContainer(
containerInfo: Container,
isConcurrent: boolean,
hydrate: boolean,
): OpaqueRoot {
return createFiberRoot(containerInfo, isConcurrent, hydrate);
}

yck: ReactDOM 源码 368行 createFiberRoot

function createFiberRoot(
containerInfo: any,
isConcurrent: boolean,
hydrate: boolean,
): FiberRoot {
const root: FiberRoot = (new FiberRootNode(containerInfo, hydrate): any);
const uninitializedFiber = createHostRootFiber(isConcurrent);
root.current = uninitializedFiber;
uninitializedFiber.stateNode = root; return root;
}

createFiberRoot函数中,首先创建了一个root: FiberRoot,然后又创建了一个uninitializedFiber: RootFiber,它们两者还是相互引用。

// 查看 FiberRoot 对象
document.getElementById('app')._reactRootContainer._internalRoot

我们下面顺便说一下FiberRoot 和 RootFiber的关系,同时拿出几个必须要要了解的属性解释一下。

ReactDom.render(
()=> (
<div>
<div></div>
<div></div>
</div>
),
document.querySelector('#root')
)

以上图片中只有FiberRoot的部分属性,想了解更多,可以查看FiberRoot的数据结构哦!!

更多内容:

react解析: React.createElement(一)

react解析: React.Children(二)

参考:

yck: 剖剖析 React 源码

Jokcy 的 《React 源码解析》: react.jokcy.me/

ps: 顺便推一下自己的个人公众号:Yopai,有兴趣的可以关注,每周不定期更新,分享可以增加世界的快乐

最新文章

  1. vs.net Web.csproj.webinfo文件
  2. python中如何避免中文是乱码
  3. json 数据 添加 删除 排序
  4. .net网站的文件上传读取进度条和断点下载
  5. Mysql_以案例为基准之查询
  6. SqlSever基础 dateadd year,增加五年
  7. Chrome调试(debugger)总是进入paused in debugger状态
  8. 在VS2010 SP1基础上安装mvc3
  9. js原生代码编写一个鼠标在页面移动坐标的检测功能,兼容各大浏览器
  10. javascript 的 split用法
  11. ZOJ 2476 Total Amount
  12. 无序数组求第k大/第k小的数
  13. UVa 11210 - Chinese Mahjong 模拟, 枚举 难度: 0
  14. 深入理解java虚拟机---jdk8新特性(二)
  15. MyEclipse中的内置浏览器中的历史记录怎么清除
  16. datatables如何让某个列中的值居中显示?
  17. SQL语句中各个部分的执行顺序(转)
  18. Jewels and Stones
  19. Java 面试题 百度/参考的答案
  20. Net Core学习笔记

热门文章

  1. 每天学点node系列-fs文件系统(续)
  2. ZooKeeper入门(三) ZooKeeper数据模型
  3. 浅入深出Vue:第一个页面
  4. 看看大神 Paul Graham 对如何学习编程的回答
  5. Spring Cloud Alibaba | Nacos服务注册与发现
  6. Spark 中 RDD的运行机制
  7. Bzoj 1079 着色方案 题解
  8. Eclipse安装STS插件
  9. 嵌入式Linux开发环境搭建,问题ping、nfs的解决
  10. 跟着大彬读源码 - Redis 5 - 对象和数据类型(上)