我们来看看React是如何挂载组件的 一个React项目有一个方法 render是整个React组件挂载的开始,也就是下面的这个方法。
ReactDOM.render(component,mountAt)
'
我们一般使用下面的方法来将组件挂载在根元素上
'
ReactDOM.render(<App />, document.getElementById("app"));
'
ReactDOM.render()方法是核心,它接收两个参数:
Component:要挂载的组件。
MountAt: document.getElementById("app"),我们再html中定义了一个根元素,其id为app,来挂载全部的React组件。
'
ReactDOM.render方法最终是调用的 ReactMount模块的render方法,如下所示:
ReactMount.render
render: function (nextElement, container, callback) {
return ReactMount._renderSubtreeIntoContainer(null, nextElement, container, callback);
},
'
ReactMount.render方法实际上又是调用了 _renderSubtreeIntoContainer方法。这个方法是核心方法,顾名思义,该方法就是 render subtree into container:将子树挂载到 container内。
'
ReactDOM.render方法的核心是调用了下边的这个方法。
瞧一瞧 _renderSubtreeIntoContainer 方法
该方法接收四个参数。
parentComponent:父组件,初始的时候这个值是null
nextElement:就是要插入的组件
container:就是要插如的容器,一般是document.getElementById('app')
callback: 插入成功后的回调。
我们将 该方法 也就是 挂载的核心方法 _renderSubtreeIntoContainer 分割为三个部分。
篇幅太长不利于阅读,所以我们分篇幅来细说。 我会以第一部分,第二部分来命名。本篇就命名为 起始篇
_renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) {
'
第一部分
'
var nextWrappedElement = new ReactElement(TopLevelWrapper, null, null, null, null, null, nextElement);
var prevComponent = instancesByReactRootID[getReactRootID(container)];------(1)
'第二部分'
if (prevComponent) {
var prevWrappedElement = prevComponent._currentElement;
var prevElement = prevWrappedElement.props;
if (shouldUpdateReactComponent(prevElement, nextElement)) {
var publicInst = prevComponent._renderedComponent.getPublicInstance();
var updatedCallback = callback && function () {
callback.call(publicInst);
};
ReactMount._updateRootComponent(prevComponent, nextWrappedElement, container, updatedCallback);
return publicInst;
} else {
ReactMount.unmountComponentAtNode(container);
}
}
'
第三部分
'
var reactRootElement = getReactRootElementInContainer(container);
var containerHasReactMarkup = reactRootElement && !!internalGetID(reactRootElement);
var containerHasNonRootReactChild = hasNonRootReactChild(container);
var shouldReuseMarkup = containerHasReactMarkup && !prevComponent && !containerHasNonRootReactChild;
var component = ReactMount._renderNewRootComponent(nextWrappedElement, container, shouldReuseMarkup, parentComponent != null ? parentComponent._reactInternalInstance._processChildContext(parentComponent._reactInternalInstance._context) : emptyObject)._renderedComponent.getPublicInstance();
if (callback) {
callback.call(component);
}
return component;
},
所以,ReactDOM.render 方法核心是调用了 ReactMount._renderSubtreeIntoContainer 方法来完成组件的挂载。