学习React (3) - 组件进阶 01 组件生命周期方法(类组件)

83 阅读3分钟

在React中,类组件的生命周期方法是指在组件的不同阶段会被自动调用的一组特定方法。这些方法可以让你在组件的创建、更新和销毁过程中执行特定操作。组件生命周期主要分为三个阶段:挂载(Mounting)、更新(Updating)和卸载(Unmounting)。下面我们详细介绍每个阶段及其对应的方法:

挂载(Mounting)

当组件实例被创建并插入到DOM中时,这一阶段的方法会依次执行:

  1. constructor(props)

    • 调用顺序:第一个被调用
    • 作用:用于初始化状态、绑定事件处理程序等。
    • 示例:
      constructor(props) {
        super(props);
        this.state = {
          count: 0
        };
      }
      
  2. static getDerivedStateFromProps(props, state)

    • 调用顺序:在constructor之后,render之前调用
    • 作用:使组件的状态从props派生出来。返回一个对象来更新状态,或者返回null表示不更新。
    • 示例:
      static getDerivedStateFromProps(nextProps, prevState) {
        if (nextProps.someValue !== prevState.someValue) {
          return { someValue: nextProps.someValue };
        }
        return null;
      }
      
  3. render()

    • 调用顺序:每次组件需要渲染UI时调用
    • 作用:根据当前状态和props输出组件的UI结构。
    • 示例:
      render() {
        return (
          <div>{this.state.count}</div>
        );
      }
      
  4. componentDidMount()

    • 调用顺序:组件已经被渲染到DOM后调用
    • 作用:适合进行数据获取、订阅等副作用操作。
    • 示例:
      componentDidMount() {
        fetch('/api/data')
          .then(response => response.json())
          .then(data => this.setState({ data }));
      }
      

更新(Updating)

当组件的props或状态发生变化时,这一阶段的方法会被依次调用:

  1. static getDerivedStateFromProps(props, state)

    • 同挂载阶段相同,每次接收新的props时调用。
  2. shouldComponentUpdate(nextProps, nextState)

    • 调用顺序:在接收到新的props或状态后,渲染之前调用
    • 作用:返回布尔值,决定组件是否需要重新渲染。默认返回true。
    • 示例:
      shouldComponentUpdate(nextProps, nextState) {
        return nextState.count !== this.state.count;
      }
      
  3. render()

    • 调用顺序:再次渲染UI
    • 作用:输出新的UI结构。
  4. getSnapshotBeforeUpdate(prevProps, prevState)

    • 调用顺序:在最近一次渲染输出(提交到DOM节点)之前调用
    • 作用:捕获一些信息(如滚动位置)以便在componentDidUpdate中使用。
    • 示例:
      getSnapshotBeforeUpdate(prevProps, prevState) {
        if (prevProps.listLength < this.props.listLength) {
          return this.listRef.scrollHeight;
        }
        return null;
      }
      
  5. componentDidUpdate(prevProps, prevState, snapshot)

    • 调用顺序:组件更新后调用
    • 作用:进行各种操作,如DOM操作、数据更新等;可以使用getSnapshotBeforeUpdate返回的值。
    • 示例:
      componentDidUpdate(prevProps, prevState, snapshot) {
        if (snapshot !== null) {
          this.listRef.scrollTop += this.listRef.scrollHeight - snapshot;
        }
      }
      

卸载(Unmounting)

当组件被从DOM中移除时,这一阶段的方法会被调用:

  1. componentWillUnmount()
    • 调用顺序:组件即将从DOM中移除前调用
    • 作用:执行清理操作,如取消订阅、清除计时器等。
    • 示例:
      componentWillUnmount() {
        clearInterval(this.timerID);
      }
      

错误处理(Error Handling)

当组件渲染过程中或生命周期方法中抛出错误时,这一阶段的方法会被调用:

  1. static getDerivedStateFromError(error)

    • 调用顺序:有错误抛出时调用
    • 作用:返回一个对象以更新状态,用于显示降级UI。
    • 示例:
      static getDerivedStateFromError(error) {
        return { hasError: true };
      }
      
  2. componentDidCatch(error, info)

    • 调用顺序:有错误抛出时调用
    • 作用:用于记录错误日志。
    • 示例:
      componentDidCatch(error, info) {
        logErrorToMyService(error, info);
      }
      

综合示例

以下是一个综合了各个生命周期方法的简单示例:

import React, { Component } from 'react';

class LifeCycleDemo extends Component {
  constructor(props) {
    super(props);
    this.state = { counter: 0 };
    this.increment = this.increment.bind(this);
  }

  static getDerivedStateFromProps(nextProps, prevState) {
    // 根据props更新状态
    return null;
  }

  shouldComponentUpdate(nextProps, nextState) {
    // 控制是否需要更新
    return true;
  }

  getSnapshotBeforeUpdate(prevProps, prevState) {
    // 获取更新前的一些状态
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    // 组件更新后执行
  }

  componentDidMount() {
    // 组件挂载后执行
  }

  componentWillUnmount() {
    // 组件卸载前执行
  }

  increment() {
    this.setState({ counter: this.state.counter + 1 });
  }

  render() {
    return (
      <div>
        <h1>Counter: {this.state.counter}</h1>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}

export default LifeCycleDemo;

通过理解和应用这些生命周期方法,你可以更好地控制React组件的行为,实现复杂的交互逻辑和优化组件性能。