资讯专栏INFORMATION COLUMN

react解析: render的FiberRoot(三)

muddyway / 3342人阅读

摘要:查看创建核心函数源码行调用函数创建是相关,不用管源码行这个指的是调用创建,下面我们将会说到对象源码行源码行函数中,首先创建了一个,然后又创建了一个,它们两者还是相互引用。

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

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

图片描述

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

ReactDOM.render(, document.getElementById("app"))

实际代码:

ReactDOM.render(React.createElement(APP, null), document.getElementById("app"));
render 函数
yck: ReactDOM 源码 702行 render

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

render(
    element: React$Element,
    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,
  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(
  ()=> (
    
), document.querySelector("#root") )

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

更多内容:

react解析: React.createElement(一)

react解析: React.Children(二)

参考:

yck: 剖剖析 React 源码

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

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106617.html

相关文章

  • React源码解析ReactDOM.render()

    摘要:一更新的方式有三种渲染接下来,我们就来看下源码二作用在提供的里渲染一个元素,并返回对该组件的引用常见的用法是这个官网网址源码服务端使用方法渲染节点是让服务端尽可能复用节点,提高性能元素容器应用渲染结束后,调用的函数错误抓取方法本质是返回 showImg(https://segmentfault.com/img/remote/1460000020064414?w=1240&h=641);...

    iKcamp 评论0 收藏0
  • 剖析 React 源码:render 流程(二)

    摘要:就是,如果你不了解这个的话可以阅读下相关文档,是应用初始化时就会生成的一个变量,值也是,并且这个值不会在后期再被改变。这是我的剖析 React 源码的第三篇文章,如果你没有阅读过之前的文章,请务必先阅读一下 第一篇文章 中提到的一些注意事项,能帮助你更好地阅读源码。 文章相关资料 React 16.8.6 源码中文注释,这个链接是文章的核心,文中的具体代码及代码行数都是依托于这个仓库 热身...

    My_Oh_My 评论0 收藏0
  • React源码解析(一)

    摘要:是整个应用的起点,包含应用挂载的目标节点,记录整个应用更新过程的各种信息是一个对象是当前应用对应的对象,即。每个节点会对应一个对象,记录节点的各种状态,比如,,这些状态更新完成后会被更新,是所对应节点的实际的实例,比如对应一个就是一个。 ReactDom.render做了什么 首先react代码分为react和react-dom两个包,react中代码量特别的少,基本就是API的定义,...

    zzbo 评论0 收藏0
  • 剖析 React 源码:render 流程(一)

    摘要:大家可以看到是构造函数构造出来的,并且内部有一个对象,这个对象是本文接下来要重点介绍的对象,接下来我们就来一窥究竟吧。在构造函数内部就进行了一步操作,那就是创建了一个对象,并挂载到了上。下一篇文章还是流程相关的内容。这是我的剖析 React 源码的第二篇文章,如果你没有阅读过之前的文章,请务必先阅读一下 第一篇文章 中提到的一些注意事项,能帮助你更好地阅读源码。 文章相关资料 React ...

    hiYoHoo 评论0 收藏0
  • ReactDom.render分析

    摘要:先检验是否存在不存在则执行传入,后的函数创建一个。方法更新执行方法,这个方法最终调用和并返回,这些进行调度算法和进行优先级判断 1.步骤 1.创建ReactRoot 2.创建FiberRoot和FiberRoot 3.创建更新 2. render方法: render( element: React$Element, container: DOMContainer, ...

    cjie 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<