先附上流程图一张

先由babel编译, 调用reactDOM.render,入参为element, container, callback, 打印出来可以看到element,container,callback分别代表着react元素、DOM原生元素,回调函数

render实际上调用的是 legacyRenderSubtreeIntoContainer函数
render: function (element, container, callback) { return legacyRenderSubtreeIntoContainer(null, element, container, false, callback); }
legacyRenderSubtreeIntoContainer 这个函数, 实际上是初始化了root, 并调用了root.render方法, 而root是由legacyCreateRootFromDOMContainer函数返回的
function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) { var root = container._reactRootContainer; if (!root) { // 初始化root root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);// Initial mount should not be batched. unbatchedUpdates(function () { if (parentComponent != null) { root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback); } else {
// 调用root的render方法 root.render(children, callback); } }); } else { ...... } }
从代码中看出, legacyCreateRootFromDOMContainer执行了两个操作, 一个是清除掉所有的子元素, 另外一个则是返回了一个 ReactRoot实例, 这里需要注意一点, root默认是同步更新的, 即isAsync 默认为false
function legacyCreateRootFromDOMContainer(container, forceHydrate) { ...// 清除所有子元素 if (!shouldHydrate) { var warned = false; var rootSibling = void 0; while (rootSibling = container.lastChild) { { if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) { warned = true; } } container.removeChild(rootSibling); } }// 默认为同步状态 var isAsync = false; return new ReactRoot(container, isAsync, shouldHydrate); }
从ReactRoot中, 我们把createContainer返回值赋给了 实例的_internalRoot, 往下看createContainer
function ReactRoot(container, isAsync, hydrate) { var root = createContainer(container, isAsync, hydrate); this._internalRoot = root; }
从createContainer看出, createC

