5.组件钩子函数

目录

1  生命周期与钩子函数

2  创建时

3  更新时

3.1  执行顺序

3.2  触发条件

3.3  componentDidUpdate()

4  卸载时


1  生命周期与钩子函数

类组件从 被挂载到页面中运行,到组件不用时卸载 之间是组件的生命周期

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

生命周期的每个阶段可以使用一些方法,这些方法称为钩子函数(很像中间件)

生命周期有三个阶段,依次是 创建时,更新时,卸载时。在下图中 constructor,render,componentDidMount,componentDidUpdate.componentWillUnmount 是钩子函数

上面这张图只是常用的钩子函数,还有很多不常用钩子函数可以去看文档

2  创建时

在创建时会依次执行 constructor,render,componentDidMount

我们测试一下这三个钩子函数的执行顺序

这三个函数的触发机制是这样的

render()每一次渲染都会触发,所以在更新的时候也会触发。由于setState()会改变组件状态导致组件渲染,组件渲染会执行render(),所以一般不在render()中调用setState()

如果实在要调用,需要给setState()一个条件,这样就不会陷入死循环,它只会提示一个warning

只有在渲染元素后才能用 document.querySelector()这种方法获取到元素,所以我们一般在componentDidMount进行渲染后的操作

3  更新时

更新时会依次触发 render()与 componentDidUpdate()

componentDidUpdate()在更新后触发,所以在componentDidUpdate()中使用setState()也要放在一个条件中使用,在componentDidUpdate()条件使用setState()不会出现warning

3.1  执行顺序

打开后会先执行父子组件的两个render(),但并不执行componentDidUpdate()

点击按钮后会再次执行render(),子组件先更新完成,所以子组件先执行componentDidUpdate

3.2  触发条件

有三种情况会触发更新

  • New props 接收到外部新的数据
  • setState() 自身设置了新的数据
  • forceUpdate() 调用forceUpdate()时会强制更新一次

在上面的例子中,通过props更新了子组件,通过setState()更新了父组件

使用forceUpdate()也可以更新组件

点击按钮后可以触发render()与componentDidUpdate()

3.3  componentDidUpdate()

componentDidUpdate()可以使用参数prevProps,prevProps表示 本次的上一次更新 的props

我们看一下prevProps顺便验证一下在componentDidUpdate()中条件使用setState(),如果上一次与这一次的props不一致就重新渲染一遍

由于我在子组件的componentDidUpdate()加入了setState(),所以子组件的componentDidUpdate()执行了两次

父组件的componentDidUpdate()没有加入setState(),所以只执行了一次

4  卸载时

测试代码是这样的

class Child extends React.Component {
  componentWillUnmount() {
    console.log('子组件的componentWillUnmount')
  }

  render() {
    return (
      <div>count是{this.props.count}</div>
    )
  }
}

class Father extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      count:0
    }
  }

  add_one = ()=>{
    this.setState({count:this.state.count + 1})
  }

  p_or_Child = ()=>{
    if (this.state.count >=1) {
      return <p>不再渲染Child组件</p>
    }

    else {
      return <Child count={this.state.count}></Child>
    }
  }

  componentWillUnmount() {
    console.log('父组件的componentWillUnmount')
  }

  render() {
    return (
      <div>
        {this.p_or_Child()}
        <button onClick={this.add_one}>+1</button>
      </div>
    )
  }
}

ReactDOM.createRoot(document.querySelector('div')).render(<Father></Father>)

点击一次后用p标签代替组件Child,这样就会触发Child卸载

定义父组件与子组件的 componentWillUnmount()

点击之前是这样的

点击之后只触发了子组件的componentWillUnmount()

通常我们会在componentWillUnmount()中清楚组件遗留的内容,比如使用setInterval()定义的定时器,当组件消失后 使用setInterval()定义的定时器 并不会随组件的消失而消失,

点之前定时器在运行

点之后定时器还在运行

所以我们需要在componentWillUnmount()进行手动清除

这样点击完毕之后定时器就不再运行了

也不是只要删除了就能触发componentWillUnmount,比如使用removeChild()删除的时候

打开的时候是这样的

点击按钮后所有组件消失,在console中并没有打印出来componentWillUnmount()设置的东西

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Suyuoa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值