资讯专栏INFORMATION COLUMN

ReactDom.render分析

cjie / 3139人阅读

摘要:先检验是否存在不存在则执行传入,后的函数创建一个。方法更新执行方法,这个方法最终调用和并返回,这些进行调度算法和进行优先级判断

1.步骤 1.创建ReactRoot 2.创建FiberRoot和FiberRoot 3.创建更新 2. render方法:
render(
    element: React$Element,
    container: DOMContainer,
    callback: ?Function,
  ) {
    invariant(
      isValidContainer(container),
      "Target container is not a DOM element.",
    );
    return legacyRenderSubtreeIntoContainer(
      null,
      element,
      container,
      false,
      callback,
    );
  },

render方法可以传入三个参数包括ReactElement、DOM的包裹节点,和渲染结束后执行的回调方法。
然后验证invariant验证container是否是有效的Dom节点。
最后返回legacyRenderSubtreeIntoContainer方法执行后的结果,再来看看这个方法的参数

function legacyRenderSubtreeIntoContainer(
  parentComponent: ?React$Component,
  children: ReactNodeList,
  container: DOMContainer,
  forceHydrate: boolean,
  callback: ?Function,
) 
这里传入五个参数,第一个是parentComponent不存在传入null,第二个是传入container的子元素,第三个是创建ReactRoot的包裹元素,第四个是协调更新的选项,第五个是渲染后的回调方法。
let root: Root = (container._reactRootContainer: any);
  if (!root) {
    // Initial mount
    root = container._reactRootContainer = legacyCreateRootFromDOMContainer(
      container,
      forceHydrate,
    );
先检验ReactRoot是否存在不存在则执行传入container,
forceHydrate后的legacyCreateRootFromDOMContainer函数创建一个ReactRoot。forceHydrate在render方法中传入的false,在Hydrate方法中传入的true,主要是为了区分服务端渲染和客户端渲染,true时未复用原来的节点适合服务端渲染,
如果是false则执行container.removeChild(rootSibling)删除所有的子节点。
然后返回通过 new ReactRoot(container, isConcurrent, shouldHydrate)
function ReactRoot(
  container: DOMContainer,
  isConcurrent: boolean,
  hydrate: boolean,
) {
  const root = createContainer(container, isConcurrent, hydrate);
  this._internalRoot = root;
}

在这个方法中调用createContainer创建root,这个方法从react-reconciler/inline.dom文件中引入:

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

在这个方法中又调用了createFiberRoot方法创建FiberRoot
在创建玩root后执行unbatchedUpdates更新,传入root。render方法更新:

unbatchedUpdates(() => {
      if (parentComponent != null) {
        root.legacy_renderSubtreeIntoContainer(
          parentComponent,
          children,
          callback,
        );
      } else {
        root.render(children, callback);
      }
    });

执行updateContainer(children, root, null, work._onCommit);方法,这个方法最终调用enqueueUpdatescheduleWork,并返回expireTime,这些进行调度算法和进行优先级判断

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

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

相关文章

  • ReactDOM.render源码解析-1

    摘要:本文将对源码做一个初步解析。首先在方法中校验参数是否合法,然后调用在中,调用拿到了的一个实例,调用拿到了,用于注入到,和作为返回值,调用开始调度过程在中,首先清理了中的所有子节点,然后了一个并返回是如何调度的是一个什么样的类的操作是在哪里 初步看了react-dom这个包的一些源码,发现其比react包要复杂得多,react包中基本不存在跨包调用的情况,他所做的也仅仅是定义了React...

    _Zhao 评论0 收藏0
  • ReactRoot与ReactWork源码分析

    摘要:在中调用获得了的实例,然后调用其中的回调函数中调用了方法。这个类主要介绍其构造函数和方法,构造函数是时调用的,方法是的回调函数中使用的。这个将在下一篇分析。另外,方法是在的回调函数中调用的,也是一个参与后面调度的关键。 在ReactDOM.render源码解析-1中介绍了第一次render的基本过程的一部分,其中产生了ReactRoot和ReactWork两个类的实例。本文介绍下Rea...

    macg0406 评论0 收藏0
  • react解析: render的FiberRoot(三)

    摘要:查看创建核心函数源码行调用函数创建是相关,不用管源码行这个指的是调用创建,下面我们将会说到对象源码行源码行函数中,首先创建了一个,然后又创建了一个,它们两者还是相互引用。 感谢 yck: 剖析 React 源码解析,本篇文章是在读完他的文章的基础上,将他的文章进行拆解和加工,加入我自己的一下理解和例子,便于大家理解。觉得yck写的真的很棒 。React 版本为 16.8.6,关于源码的...

    muddyway 评论0 收藏0
  • ReactDOM You Should

    摘要:并不是组件中的任何地方都能够使用获取结构,只对挂载后的组件生效。组件的一个特殊属性,接受一个回调函数作为参数。反之,则表示卸载失败。再看一下这段代码这个回调函数其实是没有参数的,但是,当方法变成异步方法之后,说不定就会向其注入一些参数了。 在react的组件的开发过程中,一般来说,我们并不会真正的去操作dom。只有在顶层组件的渲染的过程中,我们借助ReactDOM.render()方法...

    mo0n1andin 评论0 收藏0
  • React系列 --- 简单模拟语法(一)

    摘要:系列系列简单模拟语法一系列合成事件与二系列算法实现分析三系列从到再到四系列与部分源码解析五系列从使用了解的各种使用方案六前言我们先不讲什么语法原理先根据效果强行模拟语法使用实现一个简易版的第一步我们先用类 React系列 React系列 --- 简单模拟语法(一)React系列 --- Jsx, 合成事件与Refs(二)React系列 --- virtualdom diff算法实现分析...

    piglei 评论0 收藏0

发表评论

0条评论

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