React中的组件生命周期函数

来自菜鸟教程
跳转至:导航、​搜索

类组件可以定义将在组件生命周期的特定时间点执行的函数。 使用它们可以更好地控制组件。 以下是 React 中可用生命周期函数的概述。

以下示例是非常糟糕的 React,仅用于演示目的。


组件WillMount

componentWillMount 在组件第一次渲染之前被调用。 您可以使用它在初始渲染之前调用 setState

class Scorecard extends Component {
  componentWillMount() {
    this.setState({score: 0});
  }

  render() {
    const {playerName} = this.props;
    // `this.state` defaults to null, but since it'll be set in
    // `componentWillMount`, it can safely be destructured.
    const {score} = this.state;
    const message = `Current Score: ${score}`;
    return (
      <div>
        <h1>{playerName}</h1>
        <div>{message}</div>
      </div>
    );
  }
}

调用 setState 通常会触发重新渲染,但在 componentWillMount 中调用它不会(因为它一开始没有渲染)。


组件DidMount

componentDidMount 在组件第一次渲染后调用。 这可用于在组件出现后立即启动异步操作。

class Scorecard extends Component {
  // Other functions omitted for brevity.
  componentDidMount() {
    // You'd probably want to send an AJAX call or something,
    // but let's say they get 1000 points after the first second.
    setTimeout(() => this.setState({score: 1000}), 1000);
  }
}

componentDidMount 在服务器渲染中不会被调用。


组件WillReceiveProps

componentWillReceiveProps 在组件接收到新的 props 时被调用,但在它渲染之前。 您可以在此处调用 setState 而不会导致另一次重新渲染,因为已经有一个待处理。

class Scorecard extends Component {
  // Other functions omitted for brevity.
  componentWillReceiveProps(nextProps) {
    // `nextProps` is the new props, while `this.props` are the old ones.
    const {playerName} = this.props;
    // It is entirely possible that the new `playerName` is the same as the old one.
    if (nextProps.playerName !== playerName) {
      // Changing your name resets the score to zero.
      this.setState({score: 0});
    }
  }
}

应该组件更新

shouldComponentUpdate 在 props 或 state 改变之后(以及 componentWillReceiveProps 之后)被调用,但在它渲染之前。 它在生命周期函数中是独一无二的,因为它预计会返回一个布尔值。 如果为 false,则不会调用 render。 这对于跳过不必要的渲染并节省一些 CPU 非常有用。

class Scorecard extends Component {
  // Other functions omitted for brevity.
  shouldComponentUpdate(nextProps, nextState) {
    // Same as `componentWillReceiveProps`, `nextProps` is the
    // new props and `this.props` is the old.
    const {playerName} = this.props;
    // Ditto for `nextState` and `this.state`.
    const {score} = this.state;
    // Only `playerName` and `score` affect the display.
    // If something else changes, re-rendering would be a waste.
    return !(nextProps.playerName === playerName && nextState.score === score);
  }
}

组件WillUpdate

componentWillUpdate 在组件渲染之前和 shouldComponentUpdate 之后被调用。 它不能调用setState

class Scorecard extends Component {
  // Other functions omitted for brevity.
  componentWillUpdate(nextProps, nextState) {
    const {playerName} = this.props;
    // If `playerName` changes, log a message.
    if (nextProps.playerName !== playerName) {
      // Note that even though `componentWillReceiveProps` called `setState`, `this.state` is still the original value.
      const {score} = this.state;
      console.log(`${playerName} is now ${nextProps.playerName}.  His score of ${score} is forfeit.`);
    }
  }
}

组件DidUpdate

componentDidUpdaterender 完成后被调用。 与其他更新函数一样,它将同时具有新旧版本的 props 和 state,但使用以前的版本作为参数。

class Scorecard extends Component {
  // Other functions omitted for brevity.
  componentDidUpdate(prevProps, prevState) {
    const {playerName} = this.props;
    // You guessed it, `prevProps` are the props as they used to be and `this.props` are what they are now.
    // Ditto for `prevState` and `this.state`.
    if (prevProps.playerName !== playerName) {
      const {score} = prevState;
      console.log(`${playerName} used to be ${prevProps.playerName}.  His former score was ${score}.`);
    }
  }
}

组件WillUnmount

最后,在移除组件之前调用 componentWillUnmount。 用它来告别。

class Scorecard extends Component {
  // Other functions omitted for brevity.
  componentWillUnmount() {
    console.log('Sayonara!');
  }
}