React的生命周期分为3部分:
1、挂载阶段(mounting)
2、更新阶段(updating)
3、卸载阶段(unmounting)
图片解读:
react的生命周期分为3个阶段:挂载时,更新时和卸载时
- 挂载时生命周期函数的调用顺序:
constructor() //构造器
static getDerivedStateFromProps() //静态方法,在render之前调用,更新阶段也会执行
render() //渲染
componentDidMount() //
各个函数解释
constructor:在 React 组件挂载之前,会调用它的构造函数。在为 React.Component 子类实现构造函数时,应在其他语句之前前调用 super(props)
。否则,this.props
在构造函数中可能会出现未定义的 bug。
通常,在 React 中,构造函数仅用于以下两种情况:
在 constructor()
函数中不要调用 setState()
方法。如果你的组件需要使用内部 state,请直接在构造函数中为 this.state
赋值初始 state:
constructor(props) {
super(props);
// 不要在这里调用 this.setState()
this.state = { counter: 0 };
this.handleClick = this.handleClick.bind(this);
}
只能在构造函数中直接为 this.state
赋值。如需在其他方法中赋值,你应使用 this.setState()
替代。
要避免在构造函数中引入任何副作用或订阅。如遇到此场景,请将对应的操作放置在 componentDidMount
中。
getDerivedStateFromProps
会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。**它应返回一个对象来更新 state,如果返回 null 则不更新任何内容;**不管原因是什么,都会在每次渲染前触发此方法。
render()
方法是 class 组件中唯一必须实现的方法。
componentDidMount () 会在组件挂载后(插入 DOM 树中)立即调用。render后react就把节点渲染到了页面,该函数内部可以拿到真正的节点,因为只有render后页面才有节点,因此该方法会在render后执行。该函数调用才意味着真正的节点才产生了。该方法调用后意味着挂载阶段的结束,将开启更新阶段。
由输出顺序可以判断生命周期函数的执行顺序:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I9pFUwKJ-1582467524364)(C:\Users\joey\AppData\Roaming\Typora\typora-user-images\image-20200222161849100.png)]
- 更新阶段生命周期函数的调用顺序:
//当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下:
static getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
各个函数解释:
getDerivedStateFromProps
会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新任何内容。该方法存在于挂载和更新两个阶段,两个阶段都会被调用。(注意:因为该函数会在挂载和更新两个阶段都调用,因此如果里面返回对象更新state,会导致页面操作更新state后立即被该方法改为固定值
)
shouldComponentUpdate(nextProps, nextState)
shouldComponentUpdate(nextProps, nextState)
根据 shouldComponentUpdate()
的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。默认行为是 state 每次发生变化组件都会重新渲染。大部分情况下,我们都应该遵循默认行为。
componentDidUpdate()
会在更新后会被立即调用(需要shouldComponentUpdate(nextProps, nextState) 方法返回值为true才会执行,因为这样页面才会更新
)。首次渲染不会执行此方法。该方法给我们提供了一个组件更新后介入进来的方法,比如:我们页面有一个蒙板提示用户正在更新之类的,那么该方法会在更新完成后执行,因此可以在该方法中添加去除蒙版的操作。
-
下载阶段阶段生命周期函数:
componentWillUnmount()
会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除 timer,取消网络请求或清除在
componentDidMount()` 中创建的订阅等。componentWillUnmount()
中不应调用setState()
,因为该组件将永远不会重新渲染。组件实例卸载后,将永远不会再挂载它。
整个练习代码
import React from "react";
export default class Life extends React.Component {
//挂载阶段的生命周期函数
constructor(props) {
super(props)
this.state = { a: 1 }
console.log("constructor");
}
static getDerivedStateFromProps(props, state) {
//该方法在挂载阶段和更新阶段都会被调用
console.log("getDerivedStateFromProps");
return {
a: state.a
}
}
componentDidMount() {
//挂载阶段render之后调用,因为render方法执行后页面才有节点可以操作,该方法可以拿到真正的节点
//会在组件挂在后(插入DOM树中)立即调用,挂载阶段结束。
console.log('componentDidMount()');
}
shouldComponentUpdate(nextProps, nextState) {
//更新阶段在render之前调用,返回值来决定是否更新页面,参数nextState
//传的值是下一次更新state的值(也就是更新后的state的值,
//只是说这个时候还没调用render方法,页面还没有刷新)
console.log("shouldComponentUpdate",nextProps, nextState);
return true;
}
//会在更新后会被立即调用(`需要shouldComponentUpdate(nextProps, nextState)
//方法返回值为true才会执行,因为这样页面才会更新`)。首次渲染不会执行此方法。
componentDidUpdate(prevProps){ //
console.log("componentDidUpdate",prevProps);
}
componentWillUnmount(){
console.log('componentWillUnmount');
}
render() { //react的class组件中唯一必须实现的方法。
console.log('render', this.state);
return (
<p>{this.state.a}
<button onClick={() => {
this.setState({
a: this.state.a + 1
})
}}>+</button>
</p>
)
}
}