React生命周期(最新API讲解)
React
在更新到16+
的时候对于class
生命的组件的生命周期有了比较大的改动和调整,此文章针对新的React
生命周期来进行学习和使用。大家也可以去 官网 进行学习。
React
中class
组件的生命周期可以大致的分为一下几步:
挂载
: 组件第一次创建,第一次渲染到页面上
更新
: 组件的state
或者props
在发生变化的时候
销毁
: 组件从dom
中移除
一、挂载
- defaultProps:属性默认值
- constructor:构造函数
- static getDerivedStateFromProps(nexProps,nexState):在执行
render
方法之前执行 - render:我们重写的
render
方法 - componentDidMount:组件第一次加载完成
index.js代码:
import React from 'react'
import ReactDom from 'react-dom'
import App from './App'
ReactDom.render(<App/>, document.querySelector('#root'))
App.js 代码如下:
class App extends Component {
static defaultProps = {name: '壳子i', message: '帅'}
/* 在render前 回调此函数 */
static getDerivedStateFromProps(nexProps, nexState) {
console.log('2-Derived', nexProps, nexState)
return null
}
/* 在创建的时候执行此声明周期 */
constructor(props) {
console.log('defaultProps已经挂在完毕',App.defaultProps)
super(props);
this.state = {
n: 1
}
console.log('1-constructor')
}
/* 组件第一次挂在完成 执行 */
componentDidMount() {
console.log('3-mount-down')
}
/* 每次都会调用 */
render() {
console.log('RENDER')
return <div>
{this.state.n}
</div>
}
}
执行上面的代码会在控制台打印如下日志
我们用图来表示一下挂载流程
二、更新
- static getDerivedStateFromProps(nexProps,nexState):更新的话会在
SCU
之前执行 - shouldComponentUpdate(nextProps, nextState):数据更新时在
render
前执行 - render:我们重写的
render
方法 - getSnapshotBeforeUpdate(preProps, preState):在要渲染
DOM
之前执行 - componentDidUpdate(preProps, preState):本次更新完后执行
我们将App.js中的代码进行更改
import React, {Component} from 'react'
export default class App extends Component {
static getDerivedStateFromProps(nextProps, nextState) {
console.log('----------DerivedPropsFromState----------')
console.log(nextState)
return nextState
}
constructor() {
super();
this.state = {
counter: 0
}
}
// 我们在此去更新数据
componentDidMount() {
this.setState({counter: 1})
console.log('--------数据更新------')
}
shouldComponentUpdate(nextProps, nextState, nextContext) {
console.log('--------S C U----------')
return true
}
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log('---------SnapshotBeforeUpdate---------')
return 1
}
componentDidUpdate(prevProps, prevState, snapshot) {
console.log('----------ComponentDidUpdate')
}
render() {
console.log('--------RENDER---------')
return (
<div>
<h2>{this.state.counter}</h2>
</div>
);
}
}
控制台日志:
我们用流程图展示执行过程
为什么 getDerivedStateFromProps要设定为一个静态方法呢?
我们先来想想,如果getDerivedStateFromProps不是一个静态方法会怎么样
getDerivedStateFromProps不是静态方法,我们就可以在里面执行this.setState去对state进行更改,如果我们是在第一次的时候就去执行this.setState去修改的话那么这次是 数据的更新呢 还是数据第一次挂在呢,这个React无法感知到,所以此时声明周期是不安全的
三、卸载
- componentWillUnmount:在组件被卸载之前调用
修改App.js代码
import React, {Component, createRef} from 'react'
import ReactDom, {unmountComponentAtNode} from 'react-dom'
export default class App extends Component {
constructor() {
super();
this.state = {
counter: 0
}
this.divEl = createRef()
}
componentDidMount() {
// 直接删除元素是不会触发 组件销毁的
// this.divEl.current.remove()
console.log('----------DidMount----------')
unmountComponentAtNode(document.querySelector('#root'))
}
componentWillUnmount() {
console.log('-----------componentWillUnmount')
}
render() {
console.log('--------RENDER---------')
return (
<div /*ref={this.divEl}*/>
<h2>{this.state.counter}</h2>
</div>
);
}
}
控制台会打印如下日志,同时页面上也会空白