生命周期一共分三段:初始化,运行中,销毁。按照顺序:
初始化
getDefaultProps():Object
全局只会调用一次,为当前类生成的默认props
,会被父组件传入的同名props
覆盖。
getInitialState():Object
为当前组件生成最初的state
,此时可以访问this.props
componentWillMount
mount直译为挂载,就是组件在页面中有对应的DOM。
render
严格意义上render
不是一个生命周期环节,它只是一个生成虚拟DOM的方法。需要返回一个虚拟DOM树或者null
。
componentDidMount
组件已经被挂载DOM,生成了this.refs
,也是初始化
中唯一可以发ajax
的环节。
整个初始化阶段结束。
运行中
运行中就是组件(挂载)在页面上的阶段。当组件自己setState
或者父辈容器setState
之后会触发一次update
。
componentWillReceiveProps(newProps):void
- 父组件
update
后会render
出一个本组件的新虚拟DOM -
React
将新虚拟DOM的props
,赋值给本组件的this.props
- 在赋值之前先调用本方法,参数是新的
props
主要用于更新由props
派生的state
,这种情况下本环节就 很重要 ,比如以userId
为参数的头像组件:
var Avatar = React.createClass({
getInitialState:function(){
return {
avatar_url:''
};
},
componentDidMount:function(){
var self = this;
this.avatarAjax = $.get('/get_avatar/',{
id:this.props.id
},function(url){
self.avatarAjax = null;
this.setState({
avatar_url:url
});
});
},
componentWillReceiveProps:function(newProps){
if(newProps.id!==this.props.id){
if(this.avatarAjax){
this.avatarAjax.abort();
}
this.avatarAjax = $.get('/get_avatar/',{
id:this.props.id
},function(url){
self.avatarAjax = null;
this.setState({
avatar_url:url
});
});
}
},
render:function(){
return _('image',{
src:this.state.avatar_url
},null);
}
});
优化:
var Avatar = React.createClass({
getInitialState:function(){
return {
avatar_url:''
};
},
componentDidMount:function(){
this.update(this.props);
},
componentWillReceiveProps:function(newProps){
if(newProps.id!==this.props.id){
this.update(newProps);
}
},
render:function(){
return _('image',{
src:this.state.avatar_url
},null);
},
update:function(props){
var self = this;
$.get('/get_avatar/',{
id:props.id
},function(url){
self.avatarAjax = null;
this.setState({
avatar_url:url
});
});
},
});
shouldComponentUpdate():bool
主要用于性能优化,初期可以不必理会。用于告诉React
对于本次update
,本组件不需要重新update
。
componentWillUpdate
render
componentDidUpdate
一次更新结束。
销毁阶段
componentWillUnmount
销毁只有这一个环节,组件unmount
后就销毁了,将不再重新mount
到其他DOM
上。
var i = 0;
var content = document.getElementById('content');
var Item = React.createClass({
getInitialState:function(){
// 赋予对象 id
if(!this.itemId){
this.itemId = ++i;
}
console.log('initState: '+ this.itemId);
return {};
},
componentWillReceiveProps:function(newProps){
if(this.props.id!==newProps.id)
console.log(this.props.id,newProps.id);
},
render:function(){
return _('div',null,this.props.id);
},
componentWillUnmount:function(){
console.log('unmount: '+this.itemId);
}
});
var List = React.createClass({
componentWillUnmount:function(){
console.log('list unmount');
},
render:function(){
return _('div',null,
this.props.data.map(function(id,i){
return _(Item,{
key:i,
id:id
});
}
));
}
});
ReactDOM.render(_(List,{data:[1,2,3]}),content);
setTimeout(function() {
ReactDOM.render(_(List,{data:[1,2]}),content);
setTimeout(function() {
ReactDOM.render(_(List,{data:[1,2,3]}),content);
}, 10);
}, 10);
/* 输出为
initState: 1
initState: 2
initState: 3
unmount: 3
initState: 4
*/
这个阶段主要用来解绑已经绑定的事件,取消发出的异步请求(timeout,ajax等)。防止setState
被再次调用,并释放内存。
头像组件示例:
var Avatar = React.createClass({
getInitialState:function(){
return {
avatar_url:''
};
},
componentDidMount:function(){
this.update(this.props);
},
componentWillReceiveProps:function(newProps){
if(newProps.id!==this.props.id){
this.update(newProps);
}
},
render:function(){
return _('image',{
src:this.state.avatar_url
},null);
},
componentWillUnmount:function(){
if(self.avatarAjax){
self.avatarAjax.abort();
self.avatarAjax = null;
}
},
update:function(props){
var self = this;
if(this.avatarAjax){
this.avatarAjax.abort();
}
this.avatarAjax = $.get('/get_avatar/',{
id:props.id
},function(url){
self.avatarAjax = null;
this.setState({
avatar_url:url
});
});
},
});