react解析: render的FiberRoot(三)
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 函数
ReactDOM.render实际调用的就是下面的代码
- render(
- element: React$Element<any>,
- container: DOMContainer,
- callback: ?Function,
- ) {
- // 注意下 forceHydrate 参数,为 true 时是服务端渲染
- // 客户端调用 render 函数的话这个值永远为 false
- return legacyRenderSubtreeIntoContainer(
- null,
- element,
- container,
- false,
- callback,
- );
- }
render函数中的参数element
是 传入的组件,container
DOM节点容器,callback是回调函数。ReactDOM.render文档。
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核心函数
- function legacyCreateRootFromDOMContainer(
- container: DOMContainer,
- forceHydrate: boolean,
- ): Root {
- const isConcurrent = false;
- // 调用ReactRoot函数 创建ReactRoot, shouldHydrate是SSR相关,不用管
- return new ReactRoot(container, isConcurrent, shouldHydrate);
- }
- function ReactRoot(
- container: DOMContainer,
- isConcurrent: boolean,
- hydrate: boolean,
- ) {
- // 这个 root 指的是 FiberRoot
- const root = createContainer(container, isConcurrent, hydrate);
- this._internalRoot = root;
- }
调用createContainer 创建FiberRoot,下面我们将会说到FiberRoot 对象
FiberRoot
- export function createContainer(
- containerInfo: Container,
- isConcurrent: boolean,
- hydrate: boolean,
- ): OpaqueRoot {
- return createFiberRoot(containerInfo, isConcurrent, hydrate);
- }
- 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(一)
参考:
Jokcy 的 《React 源码解析》: react.jokcy.me/
ps: 顺便推一下自己的个人公众号:Yopai,有兴趣的可以关注,每周不定期更新,分享可以增加世界的快乐
react解析: render的FiberRoot(三)的更多相关文章
- The Road to learn React书籍学习笔记(第三章)
The Road to learn React书籍学习笔记(第三章) 代码详情 声明周期方法 通过之前的学习,可以了解到ES6 类组件中的生命周期方法 constructor() 和 render() ...
- react解析markdown文件
当当当又get到了一个新技能,使用react-markdown来直接解析markdown文件(咳咳,小菜鸟的自娱自乐) 项目中遇到了一个API的那种展示方式,类似于入门手册啥的那种,如果是一个个调用接 ...
- react 入坑笔记(三) - Props
React Props props - 参数. 组件类 React.Component 有个 defaultProps 属性,以 class xxx extend React.Component 形式 ...
- TiKV 源码解析系列文章(三)Prometheus(上)
本文为 TiKV 源码解析系列的第三篇,继续为大家介绍 TiKV 依赖的周边库 rust-prometheus,本篇主要介绍基础知识以及最基本的几个指标的内部工作机制,下篇会介绍一些高级功能的实现原理 ...
- 解析Xml文件的三种方式及其特点
解析Xml文件的三种方式 1.Sax解析(simple api for xml) 使用流式处理的方式,它并不记录所读内容的相关信息.它是一种以事件为驱动的XML API,解析速度快,占用内存少.使用 ...
- react之——render prop
在react “从上至下的数据流原则” 背景下,常规的消息传递机制就是通过prop属性,把父级数据传递给子级,这样一种数据流通模式决定了——数据的接收方子组件要被”硬植入“进数据的数据的给予方父组件, ...
- React components render order All In One
React components render order All In One components render order / components lifecycle DOM tree ren ...
- MeteoInfo-Java解析与绘图教程(三)
MeteoInfo-Java解析与绘图教程(三) 上文我们说到简单绘制色斑图(卫星云图),但那种效果可定不符合要求,一般来说,客户需要的是在地图上色斑图的叠加,或者是将图片导出分别是这两种效果 当然还 ...
- React中render Props模式
React组件复用 React组件复用的方式有两种: 1.render Props模式 2.高阶组件HOC 上面说的这两种方式并不是新的APi. 而是利用Raect自身的编码特点,演化而来的固定编码写 ...
随机推荐
- 精通并发与 Netty (二)常用的 rpc 框架
Google Protobuf 使用方式分析 对于 RPC 协议来说,最重要的就是对象的发送与接收,这就要用到序列化与反序列化,也称为编码和解码,序列化与反序列化和网络传输一般都在对应的 RPC 框架 ...
- python初识(2)
1 字符串格式占位符 1.1%s %d %% 占位符 预留 字符串 整型 (转义) name = input('name:') print ('你的名字是:%s'%(name)) 1.2 f" ...
- Codeforces Gym101518H:No Smoking, Please(最小割)
题目链接 题意 给出一个n*m的酒店,每个点是一个房间,要将这个酒店的房间划分成为两块(一块无烟区,一块吸烟区),相邻的两个房间之间有一条带权边,权值代表空气锁的面积,如果把这条边给去掉,那么需要花费 ...
- SQL系统优化
1 系统优化介绍 在我们的项目中,由于客户的使用时间较长或客户的数据量大,造成系统运行速度慢,系统性能下降就容易造成数据库阻塞.这是个非常痛苦的事情,用户的查询.新增.修改等需要花很多时间,甚至造成系 ...
- [常用命令]Git命令
取得Git仓库 初始化一个版本仓库 git init Clone远程版本库 git clone https://github.com/yhj167/yhj167.github.io.git 添加远程版 ...
- 对http请求进行过滤处理,转换成接收着需要的格式
需要在Global.asax的Application中进行初始化处理 这样:GlobalConfiguration.Configuration.MessageHandlers.Add(new Defa ...
- Java平台调用Python平台已有算法(附源码及解析)
1. 问题描述 Java平台要调用Pyhon平台已有的算法,为了减少耦合度,采用Pyhon平台提供Restful 接口,Java平台负责来调用,采用Http+Json格式交互. 2. 解决方案 2.1 ...
- 异常——cmd下javac错误:编码GBK不可映射字符
在看菜鸟教程时候用记事本创建文件,之后用notepad++编辑后,运行出现错误. 首先从信息上知道这是编码的问题了.开始试了下再notepad++上打开文件选择标签栏的“Encoding”中的“enc ...
- 1.Actor编写-ESGrain与ESRepGrain
ESGrain 生命周期 Ray中ESGrain继承自Grain扩展了Grain的生命周期.Grain的生命周期参见文档附录:1-Grain生命周期-译注.md ESGrain重写了Grain的OnA ...
- Image Classification
.caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...