React 学习笔记:组件生命周期

组件生命周期

生命周期一个事物从创建到最后消亡经历的过程,在这个过程中会有不同的状态(新生儿、少年···),所以在 16.8 版本以前生命周期只有类组件才有,函数组件是没有这个概念的,因为它没有状态,本文就是总结类组件生命周期。

了解生命周期有助于我们理解组件的运行方式、完成更复杂的组件功能、分析组件错误原因。

挂载阶段

本阶段是首次渲染 DOM ,按以下顺序执行

  1. constructor 创建组件时,最先执行(不能在这里调用 setState 方法)。如果不初始化 state 或不进行方法绑定,就不需要实现构造函数。此时可以做以下事情:
    • 初始化 state
    • 使用 bind 解决 this 指向问题等
  2. getDerivedStateFromProps 这是一个静态方法,不常用。接收两个参数:
    • 第一个参数为即将更新的props
    • 第二个参数为上一个状态的state
  3. render 每次组件渲染都会触发 渲染UI(注意: 不能调用setState() ),此时还不能在浏览器上看到。
  4. componentDidMount 组件挂载(完成DOM渲染)后立即调用。此时可以做以下事情:
    • 发送网络请求
    • DOM操作

注意

  • 如果实现了 constructor 则应该在其他语句之前调用 super(props)。否则,this.props 在构造函数中可能会出现未定义的 bug。
  • 组件创建和更新阶段会调用 getDerivedStateFromProps,该方法需要返回一个新的对象作为新的 state 或者返回 null 表示 state 状态不需要更新。
  • 在 componentDidMount 中直接调用 setState(),会再次调用 render 方法,但不会看到中间态。
import { Component } from 'react'
export default class App extends Component {
  constructor () {
    super()
    console.log('1. constructor执行')
  }
  componentDidMount () {
    console.log('3. componentDidMount执行')
  }
  render() {
    console.log('2. render执行')
    return <div>App组件</div>
  }
}

更新阶段

触发更新的操作

  • setState()
  • forceUpdate() 强制组件更新
  • 组件接收到新的props
  • 父组件更新,子组件就会重新渲染

本阶段会按照以下顺序执行生命周期钩子函数

  1. getDerivedStateFromProps 同上。
  2. shouldComponentUpdate 告知组件本身基于当前的 props 和 state 是否需要重新渲染组件,默认为 true。不能调用 setState,否则会导致无限循环调用更新。
  3. render 每次组件渲染都会触发, 渲染UI(与 挂载阶段 是同一个render)。
  4. getSnapshotBeforeUpdate 该周期函数在 render 后执行,执行之时 DOM 元素还没有被更新,该方法返回的一个 Snapshot 值,作为 componentDidUpdate 第三个参数传入。此方法的目的在于获取组件更新前的一些信息,比如组件的滚动位置之类的
  5. componentDidUpdate 组件更新(完成DOM渲染)后立即调用(首次渲染不会执行此方法)。可以获取到更新后的DOM内容。

注意
在 componentDidUpdate 中可以直接调用 setState(),但它必须被包裹在一个条件语句里,否则会导致死循环。

import { Component } from 'react'
class Child extends Component {
  render() {
    return <h1>111</h1>
  }
}
export default class App extends Component {
  state = {
    count: 0
  }	
	handleClick = () => {
    this.setState({
      count: this.state.count + 1
    })
  }
  componentDidUpdate() {
    console.log('2. componentDidUpdate执行')
  }
  render() {
    console.log('1. render执行')
    return (
      <div>
        <Child />
        <button onClick={this.handleClick}>click</button>
      </div>
    )
  }
}

卸载阶段

在组件被移除的时候(消失)触发卸载阶段

  1. componentWillUnmount 组件卸载(从页面中消失) 执行清理工作(比如:清理定时器等)。
import { Component } from 'react'
class Child extends Component {
  componentWillUnmount () {
    console.log('componentWillUnmount执行')
  }
  render() {
    return <h1>{this.props.count}</h1>
  }
}
export default class App extends Component {
  state = {
    count: 0
  }
	handleClick = () => {
    this.setState({
      count: this.state.count + 1
    })
  }
  render() {
    return (
      <div>
        { this.state.count < 5 && <Child count={this.state.count} />}
        <button onClick={this.handleClick}>打豆豆</button>
      </div>
    )
  }
}

在这里插入图片描述
我是孤城浪人,一名正在前端路上摸爬滚打的菜鸟,欢迎你的关注。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值