9. React组件生命周期

发布于:2025-08-15 ⋅ 阅读:(10) ⋅ 点赞:(0)

2. React组件生命周期

  • 2.1. 认识生命周期
    • 2.1.1. 很多事物都有从创建到销毁的整个过程,这个过程称之为生命周期;
    • 2.1.2. React组件也有自己的生命周期,了解生命周期可以让我们在最合适的地方完成想要的功能
    • 2.1.3. 生命周期和生命周期函数的关系:
      • 2.1.3.1. 生命周期是一个抽象的概念,在生命周期的整个过程,分成了很多个阶段;
        • 比如挂载阶段(Mount), 组件第一次在DOM树中被渲染的过程;
        • 比如更新阶段(Update), 组件状态发生变化时,重新更新渲染的过程;
        • 比如卸载阶段(Unmount), 组件从DOM树中移除的过程;
      • 2.1.3.2. React内部为了告诉我们当前处于那些阶段,会对组件内部实现的某些函数进行回调,这些函数就是生命周期函数
        • 比如实现componentDidMount函数组件已经挂载到DOM上时,就会回调;
        • 比如实现componentDidUpdate函数组件已经更新时,就会回调;
        • 比如实现componentWillUnmount函数组件即将被移除时,就会回调;
        • 可以在这些回调函数中编写自己的逻辑代码,来完成自己的需求功能;
    • 2.1.4. React生命周期时,主要指的是类的生命周期,因为函数式组件是没有生命周期函数的(后面可以通过hooks来模拟一些生命周期的回调,写到hooks会在进行记录)
  • 2.2. 生命周期解析
    • 2.2.1. 先来了解下最基础、最常用的生命周期函数:compentDidMountcomponentDidUpdatecomponentWillUnmount函数

    • 2.2.2. 生命周期函数如图:官网图谱地址
      在这里插入图片描述
      在这里插入图片描述

    • 2.2.3. 挂载阶段:componentDidMount

        1. 在挂载时,首先会创建一个组件实例,在创建实例的过程中,就会执行类中constructor函数(每次引入使用组件时,创建的是ReactElement, 每次调用就创建一个组件实例, 每次创建实例时,就会先执行constructor函数)
        -> 类实例
          class Person {} ->const p1 = new Person() -> 类实例
        
        1. 紧接着调用类中的render方法
        1. 挂载完成后会调用的componentDidMount函数
        1. 如下图:
          在这里插入图片描述
        1. 示例代码如下:
        • HelloWorld.jsx
          //
          import React from 'react';
        
          class HelloWorld extends React.Component {
            // 1.构造方法:constructor
            constructor () {
              console.log('HelloWorld constructor')
              super();
              this.state = {
                message: 'Hello World'
              }
            }
        
            // 2.执行render方法
            render () {
              console.log('HelloWorld render')
              return (
                <div>
                  <h2>Hello World</h2>
                  <p>Hello World是程序员的第一个代码</p>
                </div>
              )
            }
        
            // 3.组件被渲染到DOM:被挂载到DOM上
            componentDidMount () {
              console.log('HelloWorld componentDidMount')
            }
          }
        
          export default HelloWorld;
        
        • App.jsx
          import React from "react";
          import HelloWorld from "./HelloWorld";
        
          class App extends React.Component {
            render () {
              return (
                <div>
                  哈哈哈哈
                  {/* 组件每引用一次,就创建一个实例,每创建一次组件实例,就会先执行constructor函数 */}
                  <HelloWorld />
                  <HelloWorld />
                  {/* <HelloWorld />
                  <HelloWorld /> */}
                </div>
                
              )
            }
          }
        
          export default App;
        
    • 2.2.4. 更新阶段:componentDidUpdate

        1. 当数据发生更新时,执行setState方法
        1. 执行setState方法后,重新渲染页面, 重新执行render方法,它会根据最新修改之后的message,重新生成一个新的树,然后在进行diff算法,然后决定要更新那部分
        1. react会更新dom和refs,并调用componentDidUpdate方法
        1. 如下图:
          在这里插入图片描述
        • 关键代码如下;
             // 4.组件的DOM被更新完成:DOM发生更新
            componentDidUpdate () {
              /**
              *    
              * - 1. 当数据发生更新时,执行setState方法
              * - 2. 执行setState方法后,重新渲染页面, 重新执行render方法,它会根据最新修改之后的message,重新生成一个新的树,然后在进行diff算法,然后决定要更新那部分
              * - 3. react会更新dom和refs,并调用componentDidUpdate方法
              * 
              * 
              * */
              console.log('HelloWorld componentDidUpdate')
            }
          
        • 详细代码如下:
            import React from 'react';
          
            class HelloWorld extends React.Component {
              // 1.构造方法:constructor
              constructor () {
                console.log('HelloWorld constructor')
                super();
                this.state = {
                  message: 'Hello World'
                }
              }
          
              changeText () {
                this.setState({ message: '你好啊 李银河' })
              }
              // 2.执行render方法
              render () {
                const { message } = this.state
                console.log('HelloWorld render')
                return (
                  <div>
                    <h2>{message}</h2>
                    <button onClick={e => this.changeText()}>修改文本</button>
                    <p>{message}是程序员的第一个代码</p>
                  </div>
                )
              }
          
              // 3.组件被渲染到DOM:被挂载到DOM上
              componentDidMount () {
                /**
                *    
                * - 1. 在挂载时,首先会创建一个组件实例,在创建实例的过程中,就会执行类中`constructor函数`(每次引入使用组件时,创建的是ReactElement, 每次调用就创建一个组件实例, 每次创建实例时,就会先执行constructor函数)
                * - 2. 紧接着调用类中的`render方法`
                * - 3. 挂载完成后会调用的`componentDidMount函数`
                * 
                * 
                * */ 
                console.log('HelloWorld componentDidMount')
              }
          
              // 4.组件的DOM被更新完成:DOM发生更新
              componentDidUpdate () {
                /**
                *    
                * - 1. 当数据发生更新时,执行setState方法
                * - 2. 执行setState方法后,重新渲染页面, 重新执行render方法,它会根据最新修改之后的message,重新生成一个新的树,然后在进行diff算法,然后决定要更新那部分
                * - 3. react会更新dom和refs,并调用componentDidUpdate方法
                * 
                * 
                * */
                console.log('HelloWorld componentDidUpdate')
              }
            }
          
            export default HelloWorld;
          
    • 2.2.5. 卸载阶段:componentWillUnmount

        1. 当组件从 DOM 中移除时,会调用 componentWillUnmount() 方法。
        1. 如下图:
          在这里插入图片描述
        1. 示例代码:
        • 关键代码:
          // 5.组件从DOM中卸载掉:从DOM移除掉
          componentWillUnmount () {
            console.log('HelloWorld componentWillUnmount')
          }
        
        1. 完整代码:
        • HelloWorld.jsx
          import React from 'react';
        
          class HelloWorld extends React.Component {
            // 1.构造方法:constructor
            constructor () {
              console.log('HelloWorld constructor')
              super();
              this.state = {
                message: 'Hello World'
              }
            }
        
            changeText () {
              this.setState({ message: '你好啊 李银河' })
            }
            // 2.执行render方法
            render () {
              const { message } = this.state
              console.log('HelloWorld render')
              return (
                <div>
                  <h2>{message}</h2>
                  <p>{message}是程序员的第一个代码</p>
                  <button onClick={e => this.changeText()}>修改文本</button>
                </div>
              )
            }
        
            // 3.组件被渲染到DOM:被挂载到DOM上
            componentDidMount () {
              /**
              *    
              * - 1. 在挂载时,首先会创建一个组件实例,在创建实例的过程中,就会执行类中`constructor函数`(每次引入使用组件时,创建的是ReactElement, 每次调用就创建一个组件实例, 每次创建实例时,就会先执行constructor函数)
              * - 2. 紧接着调用类中的`render方法`
              * - 3. 挂载完成后会调用的`componentDidMount函数`
              * 
              * 
              * */ 
              console.log('HelloWorld componentDidMount')
            }
        
            // 4.组件的DOM被更新完成:DOM发生更新
            componentDidUpdate () {
              /**
              *    
              * - 1. 当数据发生更新时,执行setState方法
              * - 2. 执行setState方法后,重新渲染页面, 重新执行render方法,它会根据最新修改之后的message,重新生成一个新的树,然后在进行diff算法,然后决定要更新那部分
              * - 3. react会更新dom和refs,并调用componentDidUpdate方法
              * 
              * 
              * */
              console.log('HelloWorld componentDidUpdate')
            }
        
            // 5.组件从DOM中卸载掉:从DOM移除掉
            componentWillUnmount () {
              console.log('HelloWorld componentWillUnmount')
            }
          }
        
          export default HelloWorld;
        
        • App.jsx
        import React from "react";
        import HelloWorld from "./HelloWorld";
        
        class App extends React.Component {
          constructor () {
            super();
            this.state = {
              isSHowHw: true
            }
          }
          
          switchShowHw () {
            this.setState ({ isSHowHw: !this.state.isSHowHw })
          }
          render () {
            const { isSHowHw } = this.state;
            return (
              <div>
                哈哈哈哈
                {/* 组件每引用一次,就创建一个实例,每创建一次组件实例,就会先执行constructor函数 */}
                <button onClick={ e => this.switchShowHw() }>切换</button>
                { isSHowHw && <HelloWorld />}
              </div>
              
            ) 
          }
        }
        
        export default App;
        
    • 2.2.6. 开发中常用的是:constructor()、render()、componentDidMount()、componentWillUnmount()

  • 2.3. 生命周期函数
    • 2.3.1. constructor
        1. 如果不初始化state或不进行方法绑定,则不需要为React组件实现构造函数。
        1. constructor中通常只做两件事:
        • 通过给this.state赋值对戏那个初始化内部的state;
        • 为事件绑定实例(this);
    • 2.3.2 componentDidMount
        1. componentDidMount()会在组件挂载之后(插入DOM树中)立即调用
        1. componentDidMount中通过进行那些操作?
        • 2.1. 依赖于DOM的操作可以在这里进行;
        • 2.2. 再次是发送网络请求最好的地方(官方建议)
        • 2.3. 可以在此处添加一些订阅(在componentWillUnmount中取消订阅,不然会内存泄漏)
    • 2.3.3 componentDidUpdate
        1. componentDidUpdate()会在组件更新之后立即调用, 首次渲染不会执行此方法;
        • 当组件更新后,可以在此处对DOM进行操作;
        • 如果对更新前后的props进行了比较,也可以选择在此处进行网络请求(例如:当props未发生变化时,则不会执行网络请求)
    • 2.3.4 componentWillUnmount
        1. componentWillUnmount()会在组件卸载以及销毁之前直接调用。
        • 在此方法中执行必要的清理操作;
        • 例如:清楚timer, 取消网络请求或清除在componentDidMount中创建的订阅等;
  • 2.4. 不常用的生命周期函数
    • 2.4.1. 不常用的生命周期如下图:
      在这里插入图片描述

    在这里插入图片描述

    • 2.4.2. 不常用生命周期多出来这些方法:getDerivedStateFromProps()、shouldComponentUpdate()、getSnapshotBeforeUpdate()

    • 2.4.3. getDerivedStateFromProps()

        1. getDerivedStateFromProps():在更新或者第一次挂载时,如果state里面的数据需要依赖Props, 可以在这个回调函数里完成,这个函数用的非常少
        1. getDerivedStateFromProps(): state的值在任何使用时候依赖于props时候用,该方法返回一个对象来更新state
    • 2.4.4. shouldComponentUpdate ()

        1. shouldComponentUpdate(): 该生命周期函数很常用,等记录到性能优化时再详细记录;
        1. 组件是否需要更新(shouldComponentUpdate翻译:组件要不要更新),返回true或者false,默认是true。
        1. 当通过setState去更新数据的时候,render函数一般会直接执行,重新渲染,如果在shouldComponentUpdate生命周期里面返回false,render()不会执行,组件不会重新渲染。
        1. 某些情况下返回false,可以提高性能
    • 2.4.5. getSnapshotBeforeUpdate()

        1. getSnapshotBeforeUpdate():React更新DOM之前回调的一个函数,可以获取DOM更新前的一些信息(例如:滚动位置)
        1. (Snapshot:快照)在组件更新之前,获取快照,保存一些数据,返回值会作为参数传递给componentDidUpdate()方法。
      • 在这里插入图片描述
    • 2.4.6. 更详细的生命周期相关的内容,可以参考官网:官网

    • 2.4.7. 不常用生命周期函数代码示例如下:

      • 关键代码:
        // 6.不常用的生命周期补充
        shouldComponentUpdate () {
      
          // 是否需要重新更新,默认为true,重新更新render函数,重新渲染
          return true
        }
      
        getSnapshotBeforeUpdate () {
          console.log('getSnapshotBeforeUpdate')
          return {
            scrollPosition: 1000
          }
        }
      
      • 完整代码:
        import React from 'react';
      
        class HelloWorld extends React.Component {
          // 1.构造方法:constructor
          constructor () {
            console.log('HelloWorld constructor')
            super();
            this.state = {
              message: 'Hello World'
            }
          }
      
          changeText () {
            this.setState({ message: '你好啊 李银河' })
          }
          // 2.执行render方法
          render () {
            const { message } = this.state
            console.log('HelloWorld render')
            return (
              <div>
                <h2>{message}</h2>
                <p>{message}是程序员的第一个代码</p>
                <button onClick={e => this.changeText()}>修改文本</button>
              </div>
            )
          }
      
          // 3.组件被渲染到DOM:被挂载到DOM上
          componentDidMount () {
            /**
            *    
            * - 1. 在挂载时,首先会创建一个组件实例,在创建实例的过程中,就会执行类中`constructor函数`(每次引入使用组件时,创建的是ReactElement, 每次调用就创建一个组件实例, 每次创建实例时,就会先执行constructor函数)
            * - 2. 紧接着调用类中的`render方法`
            * - 3. 挂载完成后会调用的`componentDidMount函数`
            * 
            * 
            * */ 
            console.log('HelloWorld componentDidMount')
          }
      
          // 4.组件的DOM被更新完成:DOM发生更新
          componentDidUpdate (prevProps, prevState, snapshot) {
            /**
            *    
            * - 1. 当数据发生更新时,执行setState方法
            * - 2. 执行setState方法后,重新渲染页面, 重新执行render方法,它会根据最新修改之后的message,重新生成一个新的树,然后在进行diff算法,然后决定要更新那部分
            * - 3. react会更新dom和refs,并调用componentDidUpdate方法
            * 
            * 
            * */    
            console.log('HelloWorld componentDidUpdate: ', prevProps, prevState, snapshot)
          }
      
          // 5.组件从DOM中卸载掉:从DOM移除掉
          componentWillUnmount () {
            console.log('HelloWorld componentWillUnmount')
          }
      
          // 6.不常用的生命周期补充
          shouldComponentUpdate () {
      
            // 是否需要重新更新,默认为true,重新更新render函数,重新渲染, 返回false, 不执行render,不重新渲染界面
            return true
          }
      
          getSnapshotBeforeUpdate () {
            console.log('getSnapshotBeforeUpdate')
            return {
              scrollPosition: 1000
            }
          }
        }
      
        export default HelloWorld;
      

网站公告

今日签到

点亮在社区的每一天
去签到