下面是一个简单的组件 打印一下这个组件,发现实际上是一个js对象,而不是真实的dom。 那么react是如何将react组件生成js对象的呢? 这是由于咱们在建立组件的时候,使用了extends.React.Component,即继承了Component,看下Component的源码react
function Component(props, context, updater) {
this.props = props;
this.context = context;
this.refs = emptyObject;
// renderer.
this.updater = updater || ReactNoopUpdateQueue;
}
Component.prototype.setState = function (partialState, callback) {}
Component.prototype.forceUpdate = function (callback) {}
复制代码
咱们声明了一个组件,继承了Component,它的原型上有setState等方法。 小结bash
咱们在react类和咱们平时写的js类都同样,惟一的区别在与react类多了一个render()方法,输出相似“这是A组件”的结构并挂载到真实DOM上,才能触发组件的生命周期并成为DOM树的一部分。 首先咱们看下render()方法dom
咱们知道react是经过ReactDOM.render(component,monutNode)的形式进行挂载的(能够挂载自定义组件,原生dom,字符串) 挂载过程是怎么样的呢?oop
ReactDOM.render实际调用了内部的ReactMount.render,进而执行ReactMount._renderSubtreeIntoContainer。从字面意思上就能够看出是将"子DOM"插入容器的逻辑,咱们看下源码实现:ui
render: function (element, container, callback) {
return renderSubtreeIntoContainer(null, element, container, false, callback);
},
function renderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback){}
复制代码
咱们看下renderSubtreeIntoContainer的入参:this
parentComponent:当前组件的父组件,第一次渲染时为null children:要插入DOM中的组件,如helloWorld container:要插入的容器,如document.getElementById('root')spa
咱们知道,根据ReactDOM.render()的入参类型不一样,在内部经过工厂方法生成四种不一样类型的封装组件:prototype
ReactEmptyComponent(空对象)3d
ReactTextComponent(字符串)code
ReactDOMComponent(原生dom)
ReactCompositeComponent(自定义组件,这个类型才会有生命周期)
在执行挂载流程时,经过执行每种封装组件内部的mountComponent方法触发生命周期,但显然生命周期只在React自定义组件中存在,也就是ReactCompositeComponent。