React 从 v16.3 开始,对生命周期进行了渐进式的调整。废弃了一些生命周期方法和添加了一些新的生命周期方法。
原生命周期

新的生命周期

React 逐渐废弃的生命周期方法
- componentWillMount
- componentWillReceiveProps
- componentWillUpdate
虽然废弃了这几个生命周期方法,但是 React 为了遵循版本兼容,所以 v16.3 并没有删除这三个方法,并且还增加了UNSAFE_componentWillMount,UNSAFE_componentWillReceiveProps和UNSAFE_componentWillUpdate方法,在 v16.3 版本中 新旧这几个方法都可以使用。
在 v16.3 以后的 v16.x版本中,新旧的方法依旧都可以使用,但是使用不带UNSAFE_前缀的方法,将提示被弃用的警告。
在v17 将删除componentWillMount,componentWillReceiveProps和componentWillUpdate,只有带有UNSAFE_前缀新的生命周期方法可以使用。
React 新添加的生命周期方法
- getDerivedStateFromProps
- getSnapshotBeforeUpdate
组件的生命周期分为:挂载、更新、卸载。
挂载
组件创建实例并插入 DOM 时,按照下面的生命周期方法顺序调用
- constructor()
- static getDerivedStateFromProps()
componentWillMount()/UNSAFE_componentWillMount()将被弃用- render()
- componentDidMount()
在有定义static getDerivedStateFromProps()时componentWillMount()/UNSAFE_componentWillMount()将无效。
constructor()
constructor(props)
React 组件在挂载前,会调用它的构造函数,在构造函数内部必须执行一次super(props)。不能再constructor内部调用this.setState。
通常用于:
- 通过给
this.state初始化内部状态 - 为事件处理函数绑定this
static getDerivedStateFromProps()
static getDerivedStateFromProps(newProps,prevState)
是一个静态方法,父组件传入的newProps和当前组件的prevState进行比较,判断时候需要更新state,返回值对象用作更新state,如果不需要则返回null。
在render()方法之前调用,并且在初始挂载和后续更新时调用。
import * as React from "react";
class App extends React.Component{
constructor(props){
super(props);
this.state={
childDown:1,
num:0
}
}
static getDerivedStateFromProps(props,state){
if(props.isDown === state.childDown){
return {
num:state.childDown
}
}
return null
}
render(){
return(
<div>22</div>
)
}
}
componentWillMount()/UNSAFE_componentWillMount() 弃用
在挂载之前调用。在render()之前调用。在此方法中调用setState不会触发render。
有的习惯把请求放在此阶段中,但更推荐放在componentMidMount()中。
在服务器渲染时,在此方法中同步数据,但建议使用constructor来初始化数据。
render()
render()是组件中唯一必须实现的方法。
react()是作为渲染用的,可以返回以下类型
- React 元素
- 数组或fragments
- Portals
- 字符串或者数值类型
- 布尔类型或null
render() 函数应该是纯函数。不能够调用setState。
componentDidMount()
组件加载完成,能够获取真是的 DOM 在此阶段可以ajax请求和绑定事件,在此阶段绑定了时间要在componentWillUnmount()取消。在此阶段可以调用setState,触发render渲染,但会影响性能。
更新
componentWillReceiveProps()/UNSAFE_componentWillReceiveProps()弃用- static getDerivedStateFromProps()
- shouldComponentUpate()
componentWillUpdate()/UNSAFE_componentWillUpdate()弃用- render()
- getSnapshotBeforeUpdate()
- componentDidUpdate
有getDerivedStateFromProps或getSnapshotBeforeUpdate时,componentWillReceiveProps()/UNSAFE_componentWillReceiveProps()和componentWillUpdate()/UNSAFE_componentWillUpdate()无效。
componentWillReceiveProps()/UNSAFE_componentWillReceiveProps() 弃用
UNSAFE_componentWillReceiveProps(nextprops){}
在已挂载的组件接收新的props之前调用,一般用这个方法判断props的前后变化来更新state。
需要注意的是,如果父组件导致组件重新渲染,那么即使props没有更改,也会调用次方法。
该方法将被弃用,建议使用getDeviedStateFromProps。
import * as React from "react";
class App extends React.Component {
state = {
isWill: false,
};
componentWillReceiveProps(nextProps) {
if (this.props.cur !== nextProps.cur) {
this.setState({
isWill:
nextProps.cur > this.props.cur,
});
}
}
render(){
return(
<div>22</div>
)
}
}
static getDerivedStateFromProps()
和挂载阶段一致。
shouldComponentUpdate()
shouldComponentUpdate(props,state)
在已挂载的组件,当props或者state发生变化时,会在渲染前调用。
根据父组件的 props 和当前的 state 进行对比,返回true/false。决定是否触发后续的 UNSAFE_componentWillUpdate(),render()和componentDidUpdate()。
React 可能将shouldComponentUpdate()认为不严格的指令,即使state为false,也有可能导致组件重新渲染。
import * as React from "react";
class App extends React.Component {
state = {
isWill: false,
};
shouldComponentUpdate(props,state){
if(props.val !== state.val){
console.log("shouldComponentUpdate");
return true
}
}
render(){
return(
<div>22</div>
)
}
}
getSnapshotBeforeUpdate()
getSnapshotBeforeUpdate(prevProps,prevSteate)
在真是的 DOM 更新前调用。可获取一些有用的信息然后作为参数传递给componentDidUpdate()。prevProps表示更新前的props,prevState表示更新前的state。
在render()之后componentDidUpdate()之前调用。此方法的返回值(snaphot)可作为componentDidUpdate()的第三个参数使用。如不需要返回值则直接返回null。
getSnapshotBeforeUpdate()需要和componentDidUpdate()搭配。
componentDidUpdate()
componentDidUpdate(prevProps, prevState, snapshot)
该方法会在更新完成后立即调用。首次渲染不会执行此方法。
当组件更新后,可以在此处对 DOM 进行操作。
可以在此阶段使用setState,触发render()但必须包裹在一个条件语句里,以避免死循环。
卸载
- componentWillUnmount()
componentWillUnmount()
会在组件卸载和销毁之前直接调用。此方法主要用来执行一些清理工作,例如:定时器,清除事件绑定,取消网络请求。
此阶段不能调用setState,因为组件永远不会重新渲染。
总结
React 的生命周期可以查看 生命周期图谱。
虽然 React 做了向下兼容,但还是推荐大家逐渐使用新的生命周期方法。
更多详情请移步React 生命周期