【React】生命周期和钩子函数

概念

组件从被创建到挂载到页面中运行,再到组件不用时卸载的过程。

只有类组件才有生命周期。

分为三个阶段:

  1. 挂载阶段
  2. 更新阶段
  3. 销毁阶段

三个阶段

挂载阶段

钩子函数 - constructor

创建阶段触发
作用:创建数据

  • 之前定义状态是简写,完整写法是写在constructor函数中
  • 包括props之前也是简写,完整写法是写在constructor函数中
  • 包括ref【获取真实DOM元素/获取类组件实例】的创建,也要写在constructor函数中
js 复制代码
class Son extends Component {
  constructor(props) {
    // 【创建阶段,目的是创建数据】最先执行
    super()
    this.state = {
      b: props.a,
    }
    this.iptRef = createRef()
  }
  // iptRef = createRef()  // 建立ref的简写
}

钩子函数 - render

渲染阶段触发 (每次组建渲染都会触发)
作用:渲染UI
| ⚠️ 注意 :不能调用setState()
| 原因是render是每次组件渲染时触发的,如果在里面凋setState(),则组件数据发生变化,肯定要重新渲染,但是重新渲染又会触发render。就会形成死循环!!!

js 复制代码
  render() {
    return (
      <>
        hi :{this.state.b}
        <input type="text" ref={this.iptRef} />
      </>
    )
    // return <>hi :{this.props.a}</>  // props的简写
  }

钩子函数 - componentDidMount

完成DOM渲染后触发
作用:发送请求;DOM操作

js 复制代码
componentDidMount() {
    // 【组建挂载完毕,目的是:发送请求;DOM操作】完成DOM渲染后触发
    console.log('componentDidMount')
  }

执行顺序

js 复制代码
class App extends Component {
  // 挂载阶段,会经过三个钩子:constructor render componentDidMount
  constructor() {
    // 【创建阶段,目的是创建数据】最先执行
    super()
    console.log('constructor')
  }
  render() {
    // 【渲染阶段,目的是渲染UI】每次组建渲染都会触发,(注意⚠️ :不能调用setState()原因是render是每次组件渲染时触发的,如果在里面凋setState(),则组件数据发生变化,肯定要重新渲染,但是重新渲染又会触发render。就会形成死循环!!!)
    console.log('render')
    return (
      <>
      </>
    )
  }
  componentDidMount() {
    // 【组建挂载完毕,目的是:发送请求;DOM操作】完成DOM渲染后触发
    console.log('componentDidMount')
  }
}

更新阶段

更新含义:数据发生变化就会引起组件的更新

钩子函数 - render()

每次组件重新渲染(数据发生变化)执行

  1. 默认挂载阶段会执行一次
  2. 更新阶段执行
    1. 调用了setState方法
    2. forceUpdate(强制更新)
    3. props传递的数据更新了

钩子函数 - componentDidUpdate()

  1. 更新阶段执行
    1. 调用了setState方法
    2. forceUpdate(强制更新)
    3. props传递的数据更新了

| ⚠️ 注意 :不能调用setState()
| 理由同render

js 复制代码
import React, { Component } from 'react'
import ReactDOM from 'react-dom/client'
export default class App extends Component {
  // 挂载阶段,会经过三个钩子:constructor render componentDidMount
  constructor() {
    // 【创建阶段,目的是创建数据】最先执行
    super()
    this.state = {
      a: 100,
      b: 50,
    }
    console.log('constructor')
  }
  handelChange = () => {
    this.setState({
      a: this.state.a + 1,
    })
    this.state.b += 1
    this.forceUpdate() // 强更新(强制DOM更新) 如果不调用这个方法,b的数据会变化,但是,DOM无法更新
    console.log(this.state.b)
  }
  render() {
    console.log('render')
    return (
      <>
        <div>
          {this.state.a} --- {this.state.b}
        </div>
        <button onClick={this.handelChange}>修改</button>
      </>
    )
  }
  componentDidMount() {
    // 【组件挂载完毕,目的是:发送请求;DOM操作】完成DOM渲染后触发
    console.log('componentDidMount')
  }
  componentDidUpdate() {
    // 【组件更新完毕】
    console.log('componentDidUpdate')
  }
}

ReactDOM.createRoot(document.querySelector('#root')).render(<App></App>)

卸载阶段

钩子函数 - componentWillUnmount()

js 复制代码
import React, { Component } from 'react'
let timer = -1
export default class Son extends Component {
  constructor() {
    super()
    console.log(' Son子组件的constructor')

    timer = setInterval(() => {
      console.log('定时器执行')
    }, 1000)
  }
  render() {
    console.log('Son子组件的render')
    return <div>Son</div>
  }
  componentDidMount() {
    console.log('Son子组件的componentDidMount')
  }
  componentDidUpdate() {
    console.log('Son子组件的componentDidUpdate')
  }
  // 【组件卸载,执行一些清理工作】组件即将销毁的时候,要将全局的定时任务,全局变量,全局...等等销毁
  componentWillUnmount() {
    clearInterval(timer)
    console.log('Son子组件销毁了componentWillUnmount')
  }
}

父子组件的钩子函数执行顺序

父组件constructor → 父组件的render → 子组件的constructor → 子组件的render → 子组件的componentDidMount → 父组件的componentDidMount

相关推荐
灵感__idea2 小时前
Hello 算法:贪心的世界
前端·javascript·算法
killerbasd5 小时前
牧苏苏传 我不装了 4/7
前端·javascript·vue.js
吴声子夜歌5 小时前
ES6——二进制数组详解
前端·ecmascript·es6
橘子编程6 小时前
JavaScript与TypeScript终极指南
javascript·ubuntu·typescript
叫我一声阿雷吧6 小时前
JS 入门通关手册(45):浏览器渲染原理与重绘重排(性能优化核心,面试必考
javascript·前端面试·前端性能优化·浏览器渲染·浏览器渲染原理,重排重绘·reflow·repaint
大家的林语冰7 小时前
《前端周刊》尤大开源 Vite+ 全家桶,前端工业革命启动;尤大爆料 Void 云服务新产品,Vite 进军全栈开发;ECMA 源码映射规范......
前端·javascript·vue.js
jiayong237 小时前
第 8 课:开始引入组合式函数
前端·javascript·学习
天若有情6738 小时前
【C++原创开源】formort.h:一行头文件,实现比JS模板字符串更爽的链式拼接+响应式变量
开发语言·javascript·c++·git·github·开源项目·模版字符串
软件工程师文艺8 小时前
从0到1:Claude Code如何用React构建CLI应用
前端·react.js·前端框架
M ? A8 小时前
Vue 迁移 React 实战:VuReact 一键自动化转换方案
前端·vue.js·经验分享·react.js·开源·自动化·vureact