React组件生命周期:
- constructor()构造方法
constructor是ES6对类的默认方法,通过 new命令生成对象实例时自动调用该方法。并且,该方法是类中必须有的,如果没有显示定义,则会默认添加空的constructor( )方法。当存在constructor的时候⚠️必须手动调用super方法。在constructor中如果要访问this.props需要传入props
强调以下:
1.存在constructor的时候⚠️必须手动调用super方法
2.constructor中如果要访问this.props需要传入props
代码示例
class MyClass extends React.component{
constructor(props){
super(props); // 声明constructor时必须调用super方法
console.log(this.props); // 可以正常访问this.props,因为传入的props
}
}
constructor常用来初始化state
class MyClass extends React.Component {
constructor(props){
super(props);
this.state = {
list: this.props.List
};
}
}
class的静态方法实例属性也可以初始化state
class ReactCounter extends React.Component {
state = {
list: []
};
}
具体方法请参照:Class-的静态方法
- componentWillMount() 组件挂载之前
在组件挂载之前调用,且全局只调用一次。如果在这个钩子里可以setState,render后可以看到更新后的state,不会触发重复渲染。该生命周期可以发起异步请求,并setState。(React v16.3后废弃该生命周期,可以在constructor中完成设置state)
- render() 渲染组件
render是react必须定义的一个生命周期,用来渲染dom。
注意:尽量不要在render方法里面修改state,可能会触发死循环导致栈溢出。
render() {
const {nodeResultData: {res} = {}} = this.props;
if (isEmpty(res)) return noDataInfo;
const nodeResult = this.getNodeResult(res);
return (
<div className="workspace-dialog-result">
{nodeResult}
</div>
);
- componentDidMount() 组件挂载完成后
在组件挂载完成后调用,且全局只调用一次,在该生命周期函数内:
1.可以在这里使用refs,获取真实dom元素
2.该钩子内也可以发起异步请求,并在异步请求中可以进行setState
示例代码
componentDidMount() {
axios.get('/auth/getTemplate').then(res => {
const {TemplateList = []} = res;
this.setState({TemplateList});
});
}
- componentWillReceiveProps (nextProps ) props即将变化之前
props发生变化以及父组件重新渲染时都会触发该生命周期,在该钩子内可以通过参数nextProps获取变化后的props参数,通过this.props访问之前的props。该生命周期内可以进行setState。(React v16.3后废弃该生命周期,可以用新的周期 static getDerivedStateFromProps 代替)
- shouldComponentUpdate(nextProps, nextState) 是否重新渲染
组件挂载之后,每次调用setState后都会调用shouldComponentUpdate判断是否需要重新渲染组件。默认返回true,需要重新render。返回false则不触发渲染。在比较复杂的应用里,有一些数据的改变并不影响界面展示,可以在这里做判断,优化渲染效率。
- componentWillUpdate(nextProps, nextState)
shouldComponentUpdate返回true或者调用forceUpdate之后,componentWillUpdate会被调用。
不能在该钩子中setState,会触发重复循环。
- componentDidUpdate() 完成组件渲染
除了首次render之后调用componentDidMount,其它render结束之后都是调用componentDidUpdate。
该钩子内setState有可能会触发重复渲染,需要自行判断,否则会进入死循环
一般情况下:里面有定时器和异步请求时不会出现死循环。
componentDidUpdate() {
if(condition) {
this.setState({..}) // 设置state
} else {
// 不再设置state
}
}
- componentWillUnmount() 组件即将被卸载
组件被卸载的时候调用。一般在componentDidMount里面注册的事件需要在这里删除。像在didmount里面设置的定时器可以在这里面进行清楚。
生命周期图:
完整的生命周期示例
class LifeCycle extends React.Component {
constructor(props) {
super(props);
this.state = {str: "hello"};
}
componentWillMount() {
alert("componentWillMount");
}
componentDidMount() {
alert("componentDidMount");
}
componentWillReceiveProps(nextProps) {
alert("componentWillReceiveProps");
}
shouldComponentUpdate() {
alert("shouldComponentUpdate");
return true; // 记得要返回true
}
componentWillUpdate() {
alert("componentWillUpdate");
}
componentDidUpdate() {
alert("componentDidUpdate");
}
componentWillUnmount() {
alert("componentWillUnmount");
}
render() {
alert("render");
return(
<div>
<span><h2>{parseInt(this.props.num)}</h2></span>
<br />
<span><h2>{this.state.str}</h2></span>
</div>
);
}
附加:
React v16.3 新加入的生命周期 (转载)
react v16.3删掉以下三个生命周期
- componentWillMount
- componentWillReceiveProps
- componentWillUpdate
新增两个生命周期
- static getDerivedStateFromProps
- getSnapshotBeforeUpdate
- static getDerivedStateFromProps
触发时间:在组件构建之后(虚拟dom之后,实际dom挂载之前) ,以及每次获取新的props之后。
每次接收新的props之后都会返回一个对象作为新的state,返回null则说明不需要更新state.
配合componentDidUpdate,可以覆盖componentWillReceiveProps的所有用法
class Example extends React.Component {
static getDerivedStateFromProps(nextProps, prevState) {
// 没错,这是一个static
}
}
- getSnapshotBeforeUpdate
触发时间: update发生的时候,在render之后,在组件dom渲染之前。
返回一个值,作为componentDidUpdate的第三个参数。
配合componentDidUpdate, 可以覆盖componentWillUpdate的所有用法。
class Example extends React.Component {
getSnapshotBeforeUpdate(prevProps, prevState) {
// ...
}
}