最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 从0开始撸React源码-03ReactDom.render

    正文概述 掘金(大阿阳)   2021-07-24   420

    声明 : 当前react源码版本为16.8.6

    1.ReactDom

    在源码中找到ReactDom的定义

    从0开始撸React源码-03ReactDom.render

    我们熟悉的render方法的入口就在这里

    2.ReactDom.render(<App / > , root , callback)

    我们进入render方法,发现这个方法接收三个参数。

    从0开始撸React源码-03ReactDom.render

    render 方法调用了 legacyRenderSubtreeIntoContainer

    2.1 legacyRenderSubtreeIntoContainer

    这个方法会检验我们的容器上是否存在_reactRootContainer这个属性,初次渲染的时候 我们的容器上不会存在这个属性。

    从0开始撸React源码-03ReactDom.render

    我们会走入这段逻辑

     if (!root) {
        // Initial mount
        root = container._reactRootContainer = legacyCreateRootFromDOMContainer(
          container,
          forceHydrate,
        );
        ...
      }
    

    我们看一下 legacyCreateRootFromDOMContainer 这个方法

    2.2 legacyCreateRootFromDOMContainer

    从0开始撸React源码-03ReactDom.render

    这里需要解释一下参数里的forceHydrate.这里的forceHydrate的值是在 legacyRenderSubtreeIntoContainer 这个方法的第四个参数

    从0开始撸React源码-03ReactDom.render

    我们可以看到,他手动传入false.

    这个参数的作用是,是否复用容器中的DOM.主要用于服务端渲染.

    由于这个值是false,所以我们会走到 shouldHydrateDueToLegacyHeuristic 这个方法

    2.2.1 shouldHydrateDueToLegacyHeuristic

    从0开始撸React源码-03ReactDom.render

    这个方法的目的是判断是不是一个合法的挂载目标节点.这里检验了挂载目标节点中是否存在ROOT_ATTRIBUTE_NAME(data-reactroot).老版本react是用这个标识判断是否需要对容器内元素进行合并(ssr相关)

    由于我们的运行时是clint,所以 shouldHydrate 这个变量值是false.

    之后react把container中节点都给移除掉

    从0开始撸React源码-03ReactDom.render

    之后返回了一个ReactRoot

    2.3 ReactRoot

    执行了 createContainer 方法 并且在原型上声明了几个方法.(记住render方法是在这里注册的)

    从0开始撸React源码-03ReactDom.render

    2.3.1 createContainer

    这个方法的核心是创建一个FiberRoot

    从0开始撸React源码-03ReactDom.render

    我们先记住这里创建了一个FiberRoot即可.

    到这里我们获得了 legacyCreateRootFromDOMContainer 方法的执行结果.我们可以回到 legacyRenderSubtreeIntoContainer 这个方法

    从0开始撸React源码-03ReactDom.render

    我们的root现在已经有值了.之后判断了一下用户有没有callback,这里不过多解释.接下来这里涉及到了一个新的概念:batchedUpdates(批量更新).这部分需要我们在讲解更新流程时才能看到.你可以当做这里无事发生(其实就是改了个更新需要的全局变量.).所以我们直接看他的回调函数.

    if (parentComponent != null) {
        // ...
    } else {
        // 最终调用
        root.render(children, callback);
    }
    

    2.4 render

    从0开始撸React源码-03ReactDom.render

    从0开始撸React源码-03ReactDom.render

    这里又有一个概念,ExpirationTime.可以根据任务优先级进行更新.

    const expirationTime = computeExpirationForFiber(currentTime, current);
    

    之后他执行了 updateContainerAtExpirationTime 这个方法

    从0开始撸React源码-03ReactDom.render

    2.5 scheduleRootUpdate

    从0开始撸React源码-03ReactDom.render

    总结

    我们先熟悉流程,再去看每个方法具体实现细节.否则分支太多,很容易钻牛角尖.

    在ReactDom.render的过程中,我们创建了一个reactRoot,同时创建了一个FiberRoot.在FiberRoot创建的过程中,会创建一个Fiber对象.

    在root上我们创建了一个ExpirationTime和update更新对象,然后把这个更新对象加入到Fiber对象中.此过程为创建更新.

    然后我们开始进行任务调度,开始调度更新scheduleWork

    下一篇 : React-Fiber-Root


    起源地下载网 » 从0开始撸React源码-03ReactDom.render

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元