【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

相关推荐
Zheng1131 小时前
【可视化大屏】将柱状图引入到html页面中
javascript·ajax·html
john_hjy1 小时前
【无标题】
javascript
软件开发技术深度爱好者2 小时前
用HTML5+CSS+JavaScript庆祝国庆
javascript·css·html5
汪子熙2 小时前
Angular 服务器端应用 ng-state tag 的作用介绍
前端·javascript·angular.js
昨天;明天。今天。8 小时前
案例-表白墙简单实现
前端·javascript·css
安冬的码畜日常8 小时前
【玩转 JS 函数式编程_006】2.2 小试牛刀:用函数式编程(FP)实现事件只触发一次
开发语言·前端·javascript·函数式编程·tdd·fp·jasmine
小御姐@stella8 小时前
Vue 之组件插槽Slot用法(组件间通信一种方式)
前端·javascript·vue.js
GISer_Jing8 小时前
【React】增量传输与渲染
前端·javascript·面试
GISer_Jing8 小时前
WebGL在低配置电脑的应用
javascript
万叶学编程11 小时前
Day02-JavaScript-Vue
前端·javascript·vue.js