React组件的生命周期有一堆的相关函数,其实就是一推的钩子函数。在React组件创建的各个阶段触发特定的钩子函数。
可以先大概看一下下面这张图:
constructor
构造函数,在创建组件的时候调用一次。
constructor(props, context)
componentWillMount
在组件挂载之前调用一次。如果在这个函数里面调用setState,render()知道state发生变化,并且只渲染一次。
void componentWillMount()
render
render是一个React组件所必不可少的核心函数。不要在render里面修改state。也不要去读写DOM或者与服务器交互,保持render()方法的纯净。
ReactElement render()
componentDidMount
在组件挂载之后调用一次。这个时候,子组件也都挂载好了,可以在这里使用refs。
void componentDidMount()
shouldComponentUpdate
这个方法在初始化render时不会执行,当props或者state发生变化时执行。函数默认返回true,需要重新render。返回false,就不会重新render了。componentWillUpdate和componentDidUpdate方法也不会被调用。在比较复杂的应用里,有一些数据的改变并不影响界面展示,可以在这里做判断,优化渲染效率。
boolean shouldComponentUpdate(
object nextProps, object nextState
)
componentWillUpdate
shouldComponentUpdate返回true之后,componentWillUpdate会被调用。需要特别注意的是,在这个函数里面,不要用this.setState来修改状态。不然这个函数会无限循环执行。这个函数调用之后,就会把nextProps和nextState分别设置到this.props和this.state中。紧接着这个函数,就会调用render()来更新界面了。
void componentWillUpdate(
object nextProps, object nextState
)
componentDidUpdate
除了首次render之后调用componentDidMount,其它render结束之后都是调用componentDidUpdate。
void componentDidUpdate()
componentWillReceiveProps
props是父组件传递给子组件的。父组件发生render的时候子组件就会调用componentWillReceiveProps(不管props有没有更新,也不管父子组件之间有没有数据交换)。在这个回调函数里面,你可以根据属性的变化,通过调用this.setState()来更新你的组件状态,旧的属性还是可以通过this.props来获取,这里调用更新状态是安全的,并不会触发额外的render调用。
void componentWillReceiveProps(nextProps) {
this.setState({...});
}
componentWillUnmount
当组件要被从界面上移除的时候,就会调用componentWillUnmount(),在这个函数中,可以做一些组件相关的清理工作,例如取消计时器、网络请求等。
void componentWillUnmount()
下面是一个React组件生命周期的测试例子
var React = require('react');
var ReactDOM = require('react-dom');
class Parent extends React.Component {
constructor(){
super()
console.log("%cparent -- constructor","color:green");
this.state = {
name : 'Lucy'
}
}
componentWillMount(){
console.log("%cparent -- componentWillMount","color:green");
}
componentDidMount(){
console.log("%cparent -- componentDidMount","color:green");
}
componentWillReceiveProps(){
console.log("%cparent -- componentWillReceiveProps","color:green");
}
shouldComponentUpdate(){
console.log("%cparent -- shouldComponentUpdate","color:green");
return true;
}
componentWillUpdate(){
console.log("%cparent -- componentWillUpdate","color:green");
}
componentDidUpdate(){
console.log("%cparent -- componentDidUpdate","color:green");
}
componentWillUnmount(){
console.log("%cparent -- componentWillUnmount","color:green");
}
changeName(){
this.setState({name : 'Jone'})
}
unmountComponent(){
ReactDOM.unmountComponentAtNode(document.getElementById("app"));
}
render(){
console.log("%cparent -- render","color:green");
return(
<div style={{border:'1px solid #000',color:'green'}}>
<h2>Parent:</h2>
<h3>hello {this.state.name}</h3>
<button onClick={this.changeName.bind(this)}>state改变</button>
<button onClick={this.unmountComponent.bind(this)}>卸载组件</button>
<Child props1="haha"></Child>
</div>
)
}
}
class Child extends React.Component {
constructor(){
super()
console.log(" %cchild -- constructor","color:blue");
this.state = {
}
}
componentWillMount(){
console.log(" %cchild -- componentWillMount","color:blue");
}
componentDidMount(){
console.log(" %cchild -- componentDidMount","color:blue");
}
componentWillReceiveProps(){
console.log(" %cchild -- componentWillReceiveProps","color:blue");
}
shouldComponentUpdate(){
console.log(" %cchild -- shouldComponentUpdate","color:blue");
return true;
}
componentWillUpdate(){
console.log(" %cchild -- componentWillUpdate","color:blue");
}
componentDidUpdate(){
console.log(" %cchild -- componentDidUpdate","color:blue");
}
componentWillUnmount(){
console.log(" %cchild -- componentWillUnmount","color:blue");
}
changeName(){
this.setState({name : 'Jone'})
}
render(){
console.log(" %cchild -- render","color:blue");
return(
<div style={{border:'1px solid #000',margin:'10px',color:'blue'}}>
<h2>Child:</h2>
</div>
)
}
}
ReactDOM.render(
<Parent></Parent>,
document.getElementById('app')
);
测试例子截图如下:
改变父组件的state:
卸载组件后:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。