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

概念

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

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

分为三个阶段:

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

在这里插入图片描述

三个阶段

挂载阶段

钩子函数 - constructor

创建阶段触发

作用:创建数据

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

钩子函数 - render

渲染阶段触发 (每次组建渲染都会触发)

作用:渲染UI

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

钩子函数 - componentDidMount

完成DOM渲染后触发

作用:发送请求;DOM操作

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

执行顺序

在这里插入图片描述

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传递的数据更新了
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()

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
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41675812/article/details/132418410