组件从创建到销毁的一个过程,在这过程中,我们在每个特定阶段会触发一些方法。我们将这些方法称之为组件生命周期。组件生命周期主要可分为 初始化阶段、挂载阶段、更新阶段、卸载阶段。
自React V16.4发布以来,组件生命周期也产生了一些调整。本文会同时讲述两种生命周期的完整过程。
生命周期(旧)
如图所示,初始化阶段、挂载阶段、更新阶段、卸载阶段
//初始化生命周期
constructor(props) { //构造函数
super(props);
this.state = {date: new Date()};
}
static propTypes = { //对类本身增加属性
name:PropTypes.string.isRequired,
},
this.state = {date: new Date()}; //对类的实例对象增加属性
//挂载阶段生命周期
componentWillMount(){
//组件将要被挂载
}
render(){return JSX} //返回虚拟DOM
componentDidMount(){
//组件挂在完毕调用 一般用来开启定时器 开启监听 发送网络请求
}
//更新阶段生命周期
componentWillReceiveProps(nextProps){
//只要接到了新的props,componentWillReceiveProps就会被调用,即便新props与旧的完全一样
//父组件调用render 子组件的componentWillReceiveProps就会触发 不论props值是否变更
//1.上级组件render或者props变化
//2.组件第一次挂载 不执行componentWillReceiveProps
//3.触发时 可以通过this.props访问preProps
}
--> this.setState({}); //setState函数执行之后调用shouldComponentUpdate
shouldComponentUpdate(nextProps,nextState){
return boolean; //返回布尔值来控制组件是否更新 是更新 否不更新
}
--> this.forceUpdate({}); //forceUpdate函数执行之后调用componentWillUpdate
componentWillUpdate(nextProps,nextState){
//组件是否将要更新
}
render(){return JSX}
componentDidUpdate(preProps,preState){
//组件更新完毕 通常记录当前props state与preProps preState的差异 来实现业务需求
}
//卸载阶段生命周期
componentWillUnmount(){
//组件将要卸载 一般用于清除定时器
}
生命周期(新)
如图所示为React V16.4生命周期,初始化阶段、挂载阶段、更新阶段、卸载阶段。
//React V16.3将一些生命周期标记为UNSAFE_ 计划在未来的版本逐步移出这些生命周期
//UNSAFE_componentWillReceiveProps(nextProps)
//UNSAFE_componentWillMount()
//UNSAFE_componentWillUpdate(nextProps, nextState)
//初始化生命周期
constructor(props) { //构造函数
super(props);
this.state = {date: new Date()};
}
static propTypes = { //对类本身增加属性
name:PropTypes.string.isRequired,
},
//从props || state获取派生对象 不常用
//由于16.4版本的修改 每次re-rendering都会调用该生命周期
//1.父组件render 2.props change 3.this.setState() 4.this.forceUpdate()
//getDerivedStateFromProps 用来取代 componentWillReceiveProps
#1.react推出getDerivedStateFromProps生命周期的目的是为了代替componentWillReceiveProps
#2.去实现基于props派生or更新state的诉求
#特点
#1.该方法是静态的,不能在函数内部使用this
#2.该方法可以接收两个参数 来自父组件传递的props 组件自身的state
#3.该方法需要返回一个对象(或者null)
3.1react需要根据这个返回值去更新(派生) 组件的state
3.2返回的对象会与该组件的state进行合并更新 不变更的时候return null
static getDerivedStateFromProps(props, state){
if(props || state ){ 根据props||state 返回派生对象
return {...state,xxx}
}
return null
}
this.state = {date: new Date()}; //对类的实例对象增加属性
//挂载阶段生命周期
render(){return JSX}
componentDidMount(){
//组件挂在完毕调用 一般用来开启定时器 开启监听 发送网络请求
}
//更新阶段生命周期
--> this.setState({}); //setState函数执行之后调用shouldComponentUpdate
shouldComponentUpdate(nextProps,nextState){
return boolean; //返回布尔值来控制组件是否更新 是更新 否不更新
}
--> this.forceUpdate({}); //forceUpdate函数执行之后调用render
render(){return JSX} //返回的是虚拟DOM
getSnapshotBeforeUpdate(prevProps, prevState){
//在页面实际变化之前记录prevProps prevState并按业务需要返回快照对象(snapshot)
//componentDidUpdate会接受到快照对象(snapshot)
if(prevProps || prevState){
return {...snapshot}
}
}
componentDidUpdate(preProps,preState,snapshot){
//组件更新完毕 通常记录当前props state与preProps preState的差异 来实现业务需求
}
//卸载阶段生命周期
componentWillUnmount(){
//组件将要卸载 一般用于清除定时器
}
总结
新旧生命周期对比如下
- 新生命周期在计划移除componentWillReceiveProps、componentWillUpdate、componentWillMount
- 上面3个计划移除的生命周期,仍然可以使用但是会被标记UNSAFE_
- 新增了static getDerivedStateFromProps、getSnapshotBeforeUpdate
参考
- http://www.ayqy.net/blog/%E4%BB%8Ecomponentwillreceiveprops%E8%AF%B4%E8%B5%B7/
- https://segmentfault.com/a/1190000021827650 react生命周期详解
- https://www.jianshu.com/p/50fe3fb9f7c3 getDerivedStateFromProps详情解释
- https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/ react生命周期流程图
- https://www.icodebang.com/article/268804