Skip to content

类组件的生命周期

生命周期

生命周期,指的是组件从诞生到销毁会经历一系列的过程。

React 在组件的生命周期中提供了一系列的钩子函数(类似于事件),可以让开发者在函数中注入代码,这些代码会在适当的时候运行。

生命周期仅存在于类组件中,函数组件每次调用都是重新运行函数,旧的组件即刻被销毁。

旧版生命周期

React < 16.0.0

  • constructor

    • 同一个组件对象只会创建一次
    • 不能在第一次挂载到页面之前,调用this.setState,因此在构造函数中使用this.setState会报错
  • componentWillMount

    • 正常情况下,和构造函数一样,它只会运行一次
    • 可以使用this.setState,但是为了避免bug,不允许使用,因为在某些特殊情况下(如ssr),该函数可能被调用多次
  • render

    • 返回一个 React DOM,会被挂载到虚拟 DOM 树中,最终渲染到页面的真实 DOM 中
    • render 可能不只运行一次,只要有状态的更新,就会重新运行
    • 严禁使用this.setState,因为可能会导致无限递归渲染
  • componentDidMount

    • 只会执行一次

    • 可以使用setState

    • 通常情况下,会将网络请求、启动计时器等一开始需要的操作,书写到该函数中

  • 组件进入活跃状态

  • componentWillReceiveProps

    • 即将接收新的属性值

    • 参数为新的属性对象

    • 该函数可能会导致一些bug,所以不推荐使用

  • shouldComponentUpdate

    • 指示React是否要重新渲染该组件,通过返回布尔值来指定

    • 默认情况下,会直接返回true

  • componentWillUpdate

    • 组件即将被重新渲染
  • componentDidUpdate

    • 组件已经完成重新渲染
    • 往往在该函数中使用dom操作,改变元素
  • componentWillUnmount

    • 通常在该函数中销毁一些组件依赖的资源,比如计时器
jsx
import React, { Component } from 'react'

export default class OldLifeCycle extends Component {
    constructor(props) {
        super(props);
        this.state = {
            n: 0
        };
        console.log("constructor,一个新的组件诞生了!!!");
    }

    componentWillMount() {
        console.log("componentWillMount,组件即将被挂载");
    }

    componentDidMount() {
        console.log("componentDidMount,挂载完成");
    }

    componentWillReceiveProps(nextProps) {
        console.log("componentWillReceiveProps,接收到新的属性值", this.props, nextProps);
    }

    shouldComponentUpdate(nextProps, nextState) {
        console.log("shouldComponentUpdate,是否应该重新渲染", this.props, nextProps, this.state, nextState)
        if (this.props.n === nextProps.n && this.state.n === nextState.n) {
            return false;
        }
        return true;
        // return false;
    }

    componentWillUpdate(nextProps, nextState) {
        console.log("componentWillUpdate,组件即将被重新渲染");
    }
    
    componentDidUpdate(prevProps, prevState) {
        console.log("componentDidUpdate,组件已完成重新渲染", prevProps, prevState);
    }
    
    componentWillUnmount() {
        console.log("componentWillUnmount,组件被销毁")
    }

    render() {
        console.log("render渲染,返回的React元素会被挂载到虚拟DOM树中");
        return (
            <div>
                <h1>旧版生命周期组件</h1>
                <h2>属性n: {this.props.n}</h2>
                <h2>状态n:{this.state.n}</h2>
                <button onClick={() => {
                    this.setState({
                        n: this.state.n + 1
                    })
                }}>状态n+1</button>
            </div>
        )
    }
}

生命周期图示

image-20220920153615550

新版生命周期

React >= 16.0.0

React官方认为,某个数据的来源必须是单一的。

  • getDerivedStateFromProps

    • 通过参数可以获取新的属性和状态

    • 该函数是静态的

    • 该函数的返回值会覆盖掉组件状态

    • 该函数几乎是没有什么用

  • getSnapshotBeforeUpdate

    • 真实的DOM构建完成,但还未实际渲染到页面中

    • 在该函数中,通常用于实现一些附加的dom操作

    • 该函数的返回值,会作为componentDidUpdate的第三个参数

生命周期图示

image-20220927103705491