组件生命周期
生命周期一个事物从创建到最后消亡经历的过程,在这个过程中会有不同的状态(新生儿、少年···),所以在 16.8 版本以前生命周期只有类组件才有,函数组件是没有这个概念的,因为它没有状态,本文就是总结类组件生命周期。
了解生命周期有助于我们理解组件的运行方式、完成更复杂的组件功能、分析组件错误原因。
挂载阶段
本阶段是首次渲染 DOM ,按以下顺序执行
constructor
创建组件时,最先执行(不能在这里调用 setState 方法)。如果不初始化 state 或不进行方法绑定,就不需要实现构造函数。此时可以做以下事情:- 初始化 state
- 使用 bind 解决 this 指向问题等
getDerivedStateFromProps
这是一个静态方法,不常用。接收两个参数:- 第一个参数为即将更新的props
- 第二个参数为上一个状态的state
render
每次组件渲染都会触发 渲染UI(注意: 不能调用setState() ),此时还不能在浏览器上看到。componentDidMount
组件挂载(完成DOM渲染)后立即调用。此时可以做以下事情:- 发送网络请求
- DOM操作
注意:
- 如果实现了 constructor 则应该在其他语句之前调用 super(props)。否则,this.props 在构造函数中可能会出现未定义的 bug。
- 组件创建和更新阶段会调用 getDerivedStateFromProps,该方法需要返回一个新的对象作为新的 state 或者返回 null 表示 state 状态不需要更新。
- 在 componentDidMount 中直接调用 setState(),会再次调用 render 方法,但不会看到中间态。
import { Component } from 'react'
export default class App extends Component {
constructor () {
super()
console.log('1. constructor执行')
}
componentDidMount () {
console.log('3. componentDidMount执行')
}
render() {
console.log('2. render执行')
return <div>App组件</div>
}
}
更新阶段
触发更新的操作
- setState()
- forceUpdate() 强制组件更新
- 组件接收到新的props
- 父组件更新,子组件就会重新渲染
本阶段会按照以下顺序执行生命周期钩子函数
getDerivedStateFromProps
同上。shouldComponentUpdate
告知组件本身基于当前的 props 和 state 是否需要重新渲染组件,默认为 true。不能调用 setState,否则会导致无限循环调用更新。render
每次组件渲染都会触发, 渲染UI(与 挂载阶段 是同一个render)。getSnapshotBeforeUpdate
该周期函数在 render 后执行,执行之时 DOM 元素还没有被更新,该方法返回的一个 Snapshot 值,作为 componentDidUpdate 第三个参数传入。此方法的目的在于获取组件更新前的一些信息,比如组件的滚动位置之类的。componentDidUpdate
组件更新(完成DOM渲染)后立即调用(首次渲染不会执行此方法)。可以获取到更新后的DOM内容。
注意
在 componentDidUpdate 中可以直接调用 setState(),但它必须被包裹在一个条件语句里,否则会导致死循环。
import { Component } from 'react'
class Child extends Component {
render() {
return <h1>111</h1>
}
}
export default class App extends Component {
state = {
count: 0
}
handleClick = () => {
this.setState({
count: this.state.count + 1
})
}
componentDidUpdate() {
console.log('2. componentDidUpdate执行')
}
render() {
console.log('1. render执行')
return (
<div>
<Child />
<button onClick={this.handleClick}>click</button>
</div>
)
}
}
卸载阶段
在组件被移除的时候(消失)触发卸载阶段
componentWillUnmount
组件卸载(从页面中消失) 执行清理工作(比如:清理定时器等)。
import { Component } from 'react'
class Child extends Component {
componentWillUnmount () {
console.log('componentWillUnmount执行')
}
render() {
return <h1>{this.props.count}</h1>
}
}
export default class App extends Component {
state = {
count: 0
}
handleClick = () => {
this.setState({
count: this.state.count + 1
})
}
render() {
return (
<div>
{ this.state.count < 5 && <Child count={this.state.count} />}
<button onClick={this.handleClick}>打豆豆</button>
</div>
)
}
}
我是孤城浪人,一名正在前端路上摸爬滚打的菜鸟,欢迎你的关注。