react解析: render的FiberRoot(三)

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

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

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

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

实际代码:

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

render 函数

yck: ReactDOM 源码 702行 render

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

  1. render(
  2. element: React$Element<any>,
  3. container: DOMContainer,
  4. callback: ?Function,
  5. ) {
  6. // 注意下 forceHydrate 参数,为 true 时是服务端渲染
  7. // 客户端调用 render 函数的话这个值永远为 false
  8. return legacyRenderSubtreeIntoContainer(
  9. null,
  10. element,
  11. container,
  12. false,
  13. callback,
  14. );
  15. }

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

legacyRenderSubtreeIntoContainer 函数

yck: ReactDOM 源码 554行 legacyRenderSubtreeIntoContainer

  1. function legacyRenderSubtreeIntoContainer(
  2. parentComponent: ?React$Component<any, any>,
  3. children: ReactNodeList,
  4. container: DOMContainer,
  5. forceHydrate: boolean,
  6. callback: ?Function,
  7. ) {
  8. // 初始化时,container 肯定没有 _reactRootContainer属性
  9. let root: Root = (container._reactRootContainer: any);
  10. if (!root) {
  11. root = container._reactRootContainer = legacyCreateRootFromDOMContainer(
  12. container, // DOM容器节点
  13. forceHydrate, // 为false
  14. );
  15. // 暂时只说root不存在时,reactRoot的创建
  16. }
  17. }

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

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

创建FiberRoot核心函数

yck: ReactDOM 源码 504行 legacyCreateRootFromDOMContainer

  1. function legacyCreateRootFromDOMContainer(
  2. container: DOMContainer,
  3. forceHydrate: boolean,
  4. ): Root {
  5. const isConcurrent = false;
  6. // 调用ReactRoot函数 创建ReactRoot, shouldHydrate是SSR相关,不用管
  7. return new ReactRoot(container, isConcurrent, shouldHydrate);
  8. }

yck: ReactDOM 源码 368行 ReactRoot

  1. function ReactRoot(
  2. container: DOMContainer,
  3. isConcurrent: boolean,
  4. hydrate: boolean,
  5. ) {
  6. // 这个 root 指的是 FiberRoot
  7. const root = createContainer(container, isConcurrent, hydrate);
  8. this._internalRoot = root;
  9. }

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

FiberRoot

yck: ReactDOM 源码 368行 createContainer

  1. export function createContainer(
  2. containerInfo: Container,
  3. isConcurrent: boolean,
  4. hydrate: boolean,
  5. ): OpaqueRoot {
  6. return createFiberRoot(containerInfo, isConcurrent, hydrate);
  7. }

yck: ReactDOM 源码 368行 createFiberRoot

  1. function createFiberRoot(
  2. containerInfo: any,
  3. isConcurrent: boolean,
  4. hydrate: boolean,
  5. ): FiberRoot {
  6. const root: FiberRoot = (new FiberRootNode(containerInfo, hydrate): any);
  7. const uninitializedFiber = createHostRootFiber(isConcurrent);
  8. root.current = uninitializedFiber;
  9. uninitializedFiber.stateNode = root;
  10.  
  11. return root;
  12. }

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

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

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

  1. ReactDom.render(
  2. ()=> (
  3. <div>
  4. <div></div>
  5. <div></div>
  6. </div>
  7. ),
  8. document.querySelector('#root')
  9. )

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

更多内容:

react解析: React.createElement(一)

react解析: React.Children(二)

参考:

yck: 剖剖析 React 源码

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

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

react解析: render的FiberRoot(三)的更多相关文章

  1. The Road to learn React书籍学习笔记(第三章)

    The Road to learn React书籍学习笔记(第三章) 代码详情 声明周期方法 通过之前的学习,可以了解到ES6 类组件中的生命周期方法 constructor() 和 render() ...

  2. react解析markdown文件

    当当当又get到了一个新技能,使用react-markdown来直接解析markdown文件(咳咳,小菜鸟的自娱自乐) 项目中遇到了一个API的那种展示方式,类似于入门手册啥的那种,如果是一个个调用接 ...

  3. react 入坑笔记(三) - Props

    React Props props - 参数. 组件类 React.Component 有个 defaultProps 属性,以 class xxx extend React.Component 形式 ...

  4. TiKV 源码解析系列文章(三)Prometheus(上)

    本文为 TiKV 源码解析系列的第三篇,继续为大家介绍 TiKV 依赖的周边库 rust-prometheus,本篇主要介绍基础知识以及最基本的几个指标的内部工作机制,下篇会介绍一些高级功能的实现原理 ...

  5. 解析Xml文件的三种方式及其特点

    解析Xml文件的三种方式 1.Sax解析(simple api  for xml) 使用流式处理的方式,它并不记录所读内容的相关信息.它是一种以事件为驱动的XML API,解析速度快,占用内存少.使用 ...

  6. react之——render prop

    在react “从上至下的数据流原则” 背景下,常规的消息传递机制就是通过prop属性,把父级数据传递给子级,这样一种数据流通模式决定了——数据的接收方子组件要被”硬植入“进数据的数据的给予方父组件, ...

  7. React components render order All In One

    React components render order All In One components render order / components lifecycle DOM tree ren ...

  8. MeteoInfo-Java解析与绘图教程(三)

    MeteoInfo-Java解析与绘图教程(三) 上文我们说到简单绘制色斑图(卫星云图),但那种效果可定不符合要求,一般来说,客户需要的是在地图上色斑图的叠加,或者是将图片导出分别是这两种效果 当然还 ...

  9. React中render Props模式

    React组件复用 React组件复用的方式有两种: 1.render Props模式 2.高阶组件HOC 上面说的这两种方式并不是新的APi. 而是利用Raect自身的编码特点,演化而来的固定编码写 ...

随机推荐

  1. 精通并发与 Netty (二)常用的 rpc 框架

    Google Protobuf 使用方式分析 对于 RPC 协议来说,最重要的就是对象的发送与接收,这就要用到序列化与反序列化,也称为编码和解码,序列化与反序列化和网络传输一般都在对应的 RPC 框架 ...

  2. python初识(2)

    1 字符串格式占位符 1.1%s %d %% 占位符 预留 字符串 整型 (转义) name = input('name:') print ('你的名字是:%s'%(name)) 1.2 f" ...

  3. Codeforces Gym101518H:No Smoking, Please(最小割)

    题目链接 题意 给出一个n*m的酒店,每个点是一个房间,要将这个酒店的房间划分成为两块(一块无烟区,一块吸烟区),相邻的两个房间之间有一条带权边,权值代表空气锁的面积,如果把这条边给去掉,那么需要花费 ...

  4. SQL系统优化

    1 系统优化介绍 在我们的项目中,由于客户的使用时间较长或客户的数据量大,造成系统运行速度慢,系统性能下降就容易造成数据库阻塞.这是个非常痛苦的事情,用户的查询.新增.修改等需要花很多时间,甚至造成系 ...

  5. [常用命令]Git命令

    取得Git仓库 初始化一个版本仓库 git init Clone远程版本库 git clone https://github.com/yhj167/yhj167.github.io.git 添加远程版 ...

  6. 对http请求进行过滤处理,转换成接收着需要的格式

    需要在Global.asax的Application中进行初始化处理 这样:GlobalConfiguration.Configuration.MessageHandlers.Add(new Defa ...

  7. Java平台调用Python平台已有算法(附源码及解析)

    1. 问题描述 Java平台要调用Pyhon平台已有的算法,为了减少耦合度,采用Pyhon平台提供Restful 接口,Java平台负责来调用,采用Http+Json格式交互. 2. 解决方案 2.1 ...

  8. 异常——cmd下javac错误:编码GBK不可映射字符

    在看菜鸟教程时候用记事本创建文件,之后用notepad++编辑后,运行出现错误. 首先从信息上知道这是编码的问题了.开始试了下再notepad++上打开文件选择标签栏的“Encoding”中的“enc ...

  9. 1.Actor编写-ESGrain与ESRepGrain

    ESGrain 生命周期 Ray中ESGrain继承自Grain扩展了Grain的生命周期.Grain的生命周期参见文档附录:1-Grain生命周期-译注.md ESGrain重写了Grain的OnA ...

  10. Image Classification

    .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...