React.createClass()
class MyComponent extends React.Component
props
和state
被定义和配置props
state
以上方法严格按照顺序执行
该阶段主要目的就是对组件实例进行初始化配置
class MyComponent extends React.Component {
render() { return <div id={this.props.id}>Hello World!</div>;
}
};var ele = React.createElement(MyComponent, {abc:123});var ins = new MyComponent;ReactDOM.render(
<MyComponent id="123" />, //相当于ele的构造方式
document.getElementById('mount-point')
);console.log( MyComponent.prototype, //ReactComponent {}
ele instanceof MyComponent, //false
MyComponent.prototype.isPrototypeOf(ele), //false
Object.getPrototypeOf(ele), //Object
ins instanceof MyComponent, //true
MyComponent.prototype.isPrototypeOf(ins), //true
ele.type, //function MyComponent
ele.props, //{abc:123}
ele.key, //null
ele.ref //null);
new MyComponnet
的实例React.createElement()
创建的type, props, key, ref
四个属性ReactDOM.render()
, 在该方法第二个参数中传递根元素,以告知React加载内容的位置props
props
和state
被定义props
被定义完毕,组件就开始初始化state
{}
而非不定义,否则会报错props
和state
,就进入了生命周期方法的领域componentWillMount()
是第一个真正的生命周期方法render()
之前调用,所以无法访问DOM等原生UIrefs
this.props
和this.state
进行操作了,比如对props
计算后调用setState()
window resize
或Flux store
render()
贯穿了出生和成长阶段render()
应该没有副作用,这意味着不能进行 调用setState()
、访问原生UI(如ReactDOM.findDOMNode) 等一切可能引起状态改变的动作;否则会触发另一次render()
,引起死循环经过首次渲染,
render()
返回了一个根元素,该元素可能会包含若干层级的子元素
this.setState()
或forceUpdate()
触发,并需要注意多次渲染引起的潜在问题componentDidMount()
是从下至上发生的改变
props
、改变state
,或调用forceUpdate()
, 都会触发update
props
对组件自身来说是不可变的(immutable),内部写this.props.xxx = ...
会引发报错setState()
应被视为异步操作;一个常见的错误就是在一个方法里setState后尝试立即用this.state.xxx
访问那个值,这容易引起bugsetState()
向组件实例传递
props
后,成长周期中的首个生命周期方法componentWillReceiveProps(nextProp)
就可能会被调用
nextProp
可以用来和this.prop
比较,以做出决策并setState()
props
一定发生了变化;比如一个数组属性增加了新元素,此时该属性仍是同一个数组对象,React在不做深度比较的情况下无法轻易判断其是否更改,为了避免错误,仍会调用componentWillReceiveProps()
nextProps, nextState
===
来比较对象,回到数组的例子,遇到数据结构改变而对象不变时还是不能准确判断;所以Redux中的reducers纯函数返回新对象,而Immutable.js(https://facebook.github.io/immutable-js/)每次操作都返回新的不可变数据结构,这些方法都确保了可以准确验证props和state的改变Immutable.js
, 可以直接使用 ImmutableRenderMixin(https://github.com/jurassix/react-immutable-render-mixin)componentWillReceiveProps()
,也可以跳过shouldComponentUpdate()
forceUpdate()
后,组件被打上一个标记,添加到脏队列后,shouldComponentUpdate()
就被忽略掉了nextProps, nextState
componentWillMount()
类似,都在render()之前调用; 二者的目的及任务也类似,区别在于每次更新过程,该方法都会被调用refs
,可以在此时发起CSS动画等,也是调度事件的好时机setState()
,因为那将引发新一次的componentWillUpdate()
,从而陷入死循环render()
,就可以根据更新后的props和state重新应用于内容和子组件render()
返回的元素树结构,React将其和旧结构进行比较;根据每个元素上生成或指定的keys(https://facebook.github.io/react/docs/lists-and-keys.html),判断其是新建、删除还是需要更新props
以启动更新对应于出生阶段的
componentDidMount()
,在omponentDidUpdate()
中也可以访问原生UI、取得refs
或在必要的时候发起另一轮更新和渲染
prevProps, prevState
this.props
和this.state
获取的是当前的值了componentDidMount()
一样,在所有层次的子组件更新完毕之后,该方法才会被调用setState()
发起新一轮渲染,则务必小心行事,比如判断获取的高度值是否是变化过的,否则会陷入渲染死循环componentWillUnmount()
componentWillMount()
和componentDidMount()
中设置的东西清除掉,停止监听全局时间、销毁第三方库元素等;从而避免内存泄露componentWillUnmount()
,然后是其子元素,直到该节点下所有东西清理干净原文:https://www.gitbook.com/book/developmentarc/react-indepth/details