react--生命周期执行顺序

旧版 React 生命周期方法执行顺序(React 16.3 之前)

挂载阶段(Mounting)

当组件实例被创建并插入 DOM 中时,执行顺序如下:

  1. constructor: 组件的构造函数,在创建组件实例时最先调用,通常用于初始化 state 和绑定事件处理方法。
  2. componentWillMount: 在组件即将被挂载到 DOM 之前调用,此方法在服务器端渲染时也会调用。不过从 React 16 开始,它被标记为不安全的,不建议使用。
  3. render: 返回组件的 JSX 结构,用于创建虚拟 DOM。这是一个纯函数,不应该有任何副作用。
  4. componentDidMount: 组件已经被挂载到 DOM 后调用,适合进行网络请求、订阅事件、操作 DOM 等操作。

更新阶段(Updating)

当组件的 propsstate 发生变化时,会触发更新阶段,执行顺序如下:

  1. componentWillReceiveProps: 在组件接收到新的 props 时调用(初始挂载时不会调用),可以在这个方法中根据新的 props 更新 state。该方法从 React 16 开始被标记为不安全,不建议使用。
  2. shouldComponentUpdate: 返回一个布尔值,决定组件是否需要重新渲染。默认返回 true,通过合理实现这个方法可以避免不必要的渲染,提高性能。
  3. componentWillUpdate: 在组件即将重新渲染之前调用,在 shouldComponentUpdate 返回 true 之后执行。同样从 React 16 开始,它被标记为不安全,不建议使用。
  4. render: 重新渲染组件,生成新的虚拟 DOM。
  5. componentDidUpdate: 组件已经重新渲染完成后调用,可用于操作更新后的 DOM 或者进行额外的网络请求。

卸载阶段(Unmounting)

当组件从 DOM 中移除时,执行以下方法:

  • componentWillUnmount: 在组件即将被卸载之前调用,通常用于清理定时器、取消网络请求、取消订阅等操作,防止内存泄漏。

新版 React 生命周期方法执行顺序(React 16.3 及之后)

挂载阶段(Mounting)

  1. constructor: 同旧版,用于初始化 state 和绑定事件处理方法。
    static getDerivedStateFromProps: 这是一个静态方法,在组件实例化之后和接收新 props 时被调用。它应该返回一个对象来更新 state,或者返回 null 表示不更新任何内容。该方法替代了 componentWillReceivePropscomponentWillMount 的部分功能。
  2. render: 返回组件的 JSX 结构。
  3. componentDidMount: 组件挂载完成后调用,用途和旧版相同。

更新阶段(Updating)

  1. static getDerivedStateFromProps: 在组件接收到新 props 时再次调用,用于根据新 props 更新 state
  2. shouldComponentUpdate: 同旧版,决定组件是否需要重新渲染。
  3. render: 重新渲染组件。
  4. getSnapshotBeforeUpdate: 在最新的渲染输出提交到 DOM 前调用,它可以返回一个值作为 componentDidUpdate 的第三个参数,常用于保存滚动位置等信息。
  5. componentDidUpdate: 组件更新完成后调用,可获取 getSnapshotBeforeUpdate 返回的值。

卸载阶段(Unmounting)

  • componentWillUnmount: 和旧版一样,用于在组件卸载前进行清理操作。

错误处理阶段(React 16 引入)

当渲染过程、生命周期方法或子组件的构造函数中抛出错误时,会触发以下方法:

  • componentDidCatch: 在子组件抛出错误后调用,可用于捕获错误并进行错误处理,显示错误信息等。

React 17 和 React 18 的变更

  • React 17 中,UNSAFE_componentWillMount, UNSAFE_componentWillReceiveProps, 和 UNSAFE_componentWillUpdate 被标记为不推荐使用,并被替换为新的生命周期钩子。

  • React 18 中,彻底移除了所有不推荐使用的生命周期方法,并鼓励使用函数组件和 Hook,如 useState, useEffect, useContext 等。

使用函数组件和 Hooks

对于函数组件,React 提供了 Hooks,如 useState, useEffect, useContext 等,这些 Hooks 可以让你在不编写 class 的情况下使用 state 和其他 React 特性。例如,useEffect 可以看作是 componentDidMount, componentDidUpdate, 和 componentWillUnmount 的组合。这使得函数组件能够更灵活地处理副作用和更新逻辑。

生命周期示例代码及输出顺序验证

import React, { Component } from 'react';

class MyComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0
        };
        console.log('Constructor called');
    }

    static getDerivedStateFromProps(props, state) {
        console.log('getDerivedStateFromProps called');
        return null;
    }

    componentDidMount() {
        console.log('componentDidMount called');
    }

    shouldComponentUpdate(nextProps, nextState) {
        console.log('shouldComponentUpdate called');
        return nextState.count!== this.state.count;
    }

    getSnapshotBeforeUpdate(prevProps, prevState) {
        console.log('getSnapshotBeforeUpdate called');
        return null;
    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log('componentDidUpdate called');
    }

    componentWillUnmount() {
        console.log('componentWillUnmount called');
    }

    handleClick = () => {
        this.setState(prevState => ({
            count: prevState.count + 1
        }));
    };

    render() {
        console.log('render called');
        return (
            <div>
                <p>Count: {this.state.count}</p>
                <button onClick={this.handleClick}>Increment</button>
            </div>
        );
    }
}

export default MyComponent;

在上述代码中,当组件挂载时,控制台输出顺序为:

Constructor called
getDerivedStateFromProps called
render called
componentDidMount called

当点击按钮更新 state 时,控制台输出顺序为:

getDerivedStateFromProps called
shouldComponentUpdate called
render called
getSnapshotBeforeUpdate called
componentDidUpdate called

当组件卸载时,控制台输出:

componentWillUnmount called
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值