React 生命周期

  • 定义和使用

    React 中的每个组件都有一个生命周期,您可以在其三个主要阶段对其进行监视和操作。
    这三个阶段是:安装(Mounting),更新(Updating)和卸载(Unmounting)。
  • Mounting

    Mounting 意味着将元素放入DOM。
    Mounting 一个组件时,React 有四个内置方法按此顺序调用:
    1. constructor()
    2. getDerivedStateFromProps()
    3. render()
    4. componentDidMount()
    render() 方法是必需的,将始终被调用,其他方法是可选的,如果您定义它们,则将被调用。

    constructor

    初始化组件时,会首先调用 constructor() 方法,这是设置初始状态和其他初始值的自然地方。
    props 作为参数调用 constructor() 方法,您应该始终先调用 super(props) 作为开始,这将启动父级的构造方法,并允许组件从其父级继承方法(React.Component)。
    每当您制作组件时,React 都会调用构造函数方法:
    class Header extends React.Component {
      constructor(props) {
        super(props);
        this.state = {favoritecolor: "red"};
      }
      render() {
        return (
          <h1>我最喜欢的颜色是 {this.state.favoritecolor}</h1>
        );
      }
    }
    
    ReactDOM.render(<Header />, document.getElementById('root'));
    
    尝试一下

    getDerivedStateFromProps

    DOM 中呈现元素之前,将立即调用 getDerivedStateFromProps() 方法。
    这是根据初始道具设置状态对象的自然场所。
    它以状态为参数,并返回一个状态发生变化的对象。
    下面的示例以最喜欢的颜色为“红色”开始,但是 getDerivedStateFromProps() 方法根据 favcol 属性更新最喜欢的颜色:
    getDerivedStateFromProps 方法在 render 方法之前被调用:
    class Header extends React.Component {
      constructor(props) {
        super(props);
        this.state = {favoritecolor: "red"};
      }
      static getDerivedStateFromProps(props, state) {
        return {favoritecolor: props.favcol };
      }
      render() {
        return (
          <h1>我最喜欢的颜色是 {this.state.favoritecolor}</h1>
        );
      }
    }
    
    ReactDOM.render(<Header favcol="yellow" />, document.getElementById('root'));
    
    尝试一下

    render

    render() 方法是必需的,并且是实际将 HTML 输出到 DOM 的方法。
    一个带有简单 render() 方法的简单组件:
    class Header extends React.Component {
      render() {
        return (
          <h1>这是 Header 组件的内容 </h1>
        );
      }
    }
    
    ReactDOM.render(<Header />, document.getElementById('root'));
    
    尝试一下

    componentDidMount

    呈现组件后,将调用 componentDidMount() 方法。
    在这里运行要求将组件已放置在 DOM 中的语句。
    起初,我最喜欢的颜色是红色,但请稍等一会,然后改为黄色:
    class Header extends React.Component {
      constructor(props) {
        super(props);
        this.state = {favoritecolor: "red"};
      }
      componentDidMount() {
        setTimeout(() => {
          this.setState({favoritecolor: "yellow"})
        }, 1000)
      }
      render() {
        return (
          <h1>我最喜欢的颜色是 {this.state.favoritecolor}</h1>
        );
      }
    }
    
    ReactDOM.render(<Header />, document.getElementById('root'));
    
    尝试一下
  • Updating

    生命周期的下一个阶段是何时更新组件。
    只要组件的状态或道具发生变化,组件就会更新。
    当组件更新时,React 有五个内置方法按此顺序调用:
    1. getDerivedStateFromProps()
    2. shouldComponentUpdate()
    3. render()
    4. getSnapshotBeforeUpdate()
    5. componentDidUpdate()
    render() 方法是必需的,将始终被调用,其他方法是可选的,如果您定义它们,则将被调用。

    getDerivedStateFromProps

    同样在更新时,调用 getDerivedStateFromProps 方法。 这是组件更新时调用的第一个方法。
    这仍然是根据初始 Props 设置 state 对象的自然场所。
    下面的示例有一个按钮,将喜欢的颜色更改为蓝色,但是由于调用了 getDerivedStateFromProps() 方法,该方法使用 favcol 属性中的颜色更新状态,所以喜欢的颜色仍呈现为黄色。
    如果组件得到更新,则调用 getDerivedStateFromProps() 方法:
    class Header extends React.Component {
      constructor(props) {
        super(props);
        this.state = {favoritecolor: "red"};
      }
      static getDerivedStateFromProps(props, state) {
        return {favoritecolor: props.favcol };
      }
      changeColor = () => {
        this.setState({favoritecolor: "blue"});
      }
    
      render() {
        return (
          <div>
          <h1>我最喜欢的颜色是 {this.state.favoritecolor}</h1>
          <button type="button" onClick={this.changeColor}>点击我更换颜色</button>
          </div>
        );
      }
    }
    
    
    ReactDOM.render(<Header favcol="yellow" />, document.getElementById('root'));
    
    尝试一下

    shouldComponentUpdate

    shouldComponentUpdate() 方法中,您可以返回一个布尔值,该值指定 React 是否应继续进行渲染。
    默认值是 true
    下面的示例显示了 shouldComponentUpdate() 方法返回 false 时发生的情况;停止在任何更新时渲染组件:
    class Header extends React.Component {
      constructor(props) {
        super(props);
        this.state = {favoritecolor: "red"};
      }
      shouldComponentUpdate() {
        return false;
      }
      changeColor = () => {
        this.setState({favoritecolor: "blue"});
      }
    
      render() {
        return (
          <div>
          <h1>我最喜欢的颜色是 {this.state.favoritecolor}</h1>
          <button type="button" onClick={this.changeColor}>点击我更换颜色</button>
          </div>
        );
      }
    }
    
    ReactDOM.render(<Header />, document.getElementById('root'));
    
    尝试一下
    与上面的示例相同,但是这一次 shouldComponentUpdate() 方法返回 true
    class Header extends React.Component {
      constructor(props) {
        super(props);
        this.state = {favoritecolor: "red"};
      }
      shouldComponentUpdate() {
        return true;
      }
      changeColor = () => {
        this.setState({favoritecolor: "blue"});
      }
    
      render() {
        return (
          <div>
          <h1>我最喜欢的颜色是 {this.state.favoritecolor}</h1>
          <button type="button" onClick={this.changeColor}>点击我更换颜色</button>
          </div>
        );
      }
    }
    
    ReactDOM.render(<Header />, document.getElementById('root'));
    
    尝试一下

    render

    当然,当组件更新时,将调用 render() 方法,它必须使用新的更改将HTML重新呈现到 DOM
    下面的示例有一个按钮,可将最喜欢的颜色更改为蓝色;单击按钮以更改组件的状态:
    class Header extends React.Component {
      constructor(props) {
        super(props);
        this.state = {favoritecolor: "red"};
      }
      changeColor = () => {
        this.setState({favoritecolor: "blue"});
      }
    
      render() {
        return (
          <div>
          <h1>我最喜欢的颜色是 {this.state.favoritecolor}</h1>
          <button type="button" onClick={this.changeColor}>点击我更换颜色</button>
          </div>
        );
      }
    }
    
    ReactDOM.render(<Header />, document.getElementById('root'));
    
    尝试一下

    getSnapshotBeforeUpdate

    getSnapshotBeforeUpdate() 方法中,您可以在更新之前访问道具和状态,这意味着即使在更新之后,也可以检查更新之前的值。
    如果存在 getSnapshotBeforeUpdate() 方法,则还应该包括 componentDidUpdate() 方法,否则会出现错误。
    下面的示例可能看起来很复杂,但是它所做的就是:
    安装组件时,将使用喜欢的颜色“红色”渲染该组件。
    安装完组件后,计时器会更改状态,一秒钟后,喜欢的颜色将变为“黄色”。
    此操作将触发更新阶段,并且由于此组件具有 getSnapshotBeforeUpdate() 方法,因此将执行此方法,并将消息写入空 DIV1 元素。
    然后执行 componentDidUpdate() 方法,并在空的 DIV2 元素中写入一条消息。
    使用 getSnapshotBeforeUpdate() 方法找出更新前状态对象的外观:
    class Header extends React.Component {
      constructor(props) {
        super(props);
        this.state = {favoritecolor: "red"};
      }
      componentDidMount() {
        setTimeout(() => {
          this.setState({favoritecolor: "yellow"})
        }, 1000)
      }
      getSnapshotBeforeUpdate(prevProps, prevState) {
        document.getElementById("div1").innerHTML =
        "在更新之前,最喜欢的颜色是:" + prevState.favoritecolor;
      }
      componentDidUpdate() {
        document.getElementById("div2").innerHTML =
        "更新后的最喜欢的颜色是:" + this.state.favoritecolor;
      }
      render() {
        return (
          <div>
            <h1>我最喜欢的颜色是 {this.state.favoritecolor}</h1>
            <div id="div1"></div>
            <div id="div2"></div>
          </div>
        );
      }
    }
    
    ReactDOM.render(<Header />, document.getElementById('root'));
    
    尝试一下

    componentDidUpdate

    DOM 中更新组件后,将调用 componentDidUpdate 方法。
    下面的示例可能看起来很复杂,但是它所做的就是:
    安装组件时,将使用喜欢的颜色“红色”渲染该组件。
    安装组件后,计时器将更改状态,并且颜色变为“黄色”。
    此操作将触发更新阶段,并且由于此组件具有 componentDidUpdate 方法,因此将执行此方法并在空 DIV 元素中写入一条消息;在 DOM 中呈现更新后,将调用 componentDidUpdate 方法:
    class Header extends React.Component {
      constructor(props) {
        super(props);
        this.state = {favoritecolor: "red"};
      }
      componentDidMount() {
        setTimeout(() => {
          this.setState({favoritecolor: "yellow"})
        }, 1000)
      }
      componentDidUpdate() {
        document.getElementById("mydiv").innerHTML =
        "更新后的最喜欢的颜色是:" + this.state.favoritecolor;
      }
      render() {
        return (
          <div>
          <h1>我最喜欢的颜色是 {this.state.favoritecolor}</h1>
          <div id="mydiv"></div>
          </div>
        );
      }
    }
    
    ReactDOM.render(<Header />, document.getElementById('root'));
    
    尝试一下
  • Unmounting

    生命周期的下一个阶段是从 DOM 中删除组件,或者像 React 一样调用它进行卸载。
    当组件卸载时,React 只有一个内置方法可以调用:
    • componentWillUnmount()

    componentWillUnmount

    当组件即将从 DOM 中删除时,将调用 componentWillUnmount 方法。
    下面示例单击按钮删除标题:
    class Container extends React.Component {
      constructor(props) {
        super(props);
        this.state = {show: true};
      }
      delHeader = () => {
        this.setState({show: false});
      }
      render() {
        let myheader;
        if (this.state.show) {
          myheader = <Child />;
        };
        return (
          <div>
          {myheader}
          <button type="button" onClick={this.delHeader}>单击按钮删除标题</button>
          </div>
        );
      }
    }
    
    class Child extends React.Component {
      componentWillUnmount() {
        alert("名为Header的组件即将被卸载。");
      }
      render() {
        return (
          <h1>Hello World!</h1>
        );
      }
    }
    
    ReactDOM.render(<Container />, document.getElementById('root'));
    
    尝试一下