【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

相关推荐
Michael.Scofield3 分钟前
vue-axios跨域问题
前端·javascript·vue.js
zru_960239 分钟前
Vue 常用组件介绍博客
前端·javascript·vue.js
ConardLi1 小时前
MCP + 数据库,一种比 RAG 检索效果更好的新方式!
javascript·数据库·人工智能
m0_616188492 小时前
PDF预览-搜索并高亮文本
开发语言·javascript·ecmascript
美美打不死2 小时前
webpack js 逆向 --- 个人记录
开发语言·javascript·webpack
我是哈哈hh2 小时前
【Vue】 核心特性实战解析:computed、watch、条件渲染与列表渲染
前端·javascript·vue.js·前端框架·vue·语法基础
前端Hardy3 小时前
HTML&CSS:超好看的收缩展开菜单
javascript·css·html
Riesenzahn3 小时前
你使用过css3的:root吗?说说你对它的理解
前端·javascript
前端Hardy3 小时前
HTML&CSS:哇塞!Three.js 打造的 3D 交互平面,鼠标滑动纹理如梦幻般变形!
javascript·css·html
Riesenzahn3 小时前
在js中undefined和undeclared有什么区别?
前端·javascript