【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

相关推荐
meilindehuzi_a1 小时前
Vue3组件样式隔离与组件通信实战:从 scoped、props 校验到记事本应用
前端·javascript·vue.js
LaughingZhu1 小时前
Product Hunt 每日热榜 | 2026-07-28
前端·神经网络·react.js·搜索引擎·前端框架
Highcharts.js8 小时前
教程:基于 React + Highcharts 构建一个单页应用程序、按需数据拉取与图表渲染
开发语言·前端·数据结构·react.js·前端框架·highcharts·页面应用
To_OC9 小时前
我被 useState 坑了两次之后,终于把它的脾气摸透了
前端·javascript·react.js
浮生望9 小时前
React useState 深度解析:异步更新、闭包陷阱与惰性初始化的底层逻辑
react.js
Patrick_Wilson12 小时前
从 React 到 Flutter:写给前端的一张跨端知识地图
前端·flutter·react.js
kyriewen13 小时前
我review了一份Vibe Coding写的前端代码——能跑,但5个地方迟早要命
前端·javascript·ai编程
Hilaku16 小时前
为什么在 2026 年,MPA(多页面应用)正在悄悄复辟?
前端·javascript·程序员
悟空瞎说16 小时前
iOS 高效绘图
javascript
触底反弹16 小时前
🔥 从 MySQL 到 Milvus:用 AI 日记本项目搞懂向量数据库和 RAG
javascript·人工智能·面试