Skip to content

React 生命周期管理

前言

生命周期已经很久没有考过了

但是在我刚接触 React 的时候,这是个必学的知识点

相对应的 Vue ,小程序也有生命周期

你是否遇到过这样的问题:

  • 组件的生命周期有哪些?为什么要有生命周期函数?
  • 我应该生命时候去获取后台数据?为什么很多教程都推荐用 componentDidMount?用 componentWillMount 有什么问题?
  • 为什么 setState 卸载这里造成了重复渲染多次?
  • setState 在这里写合适吗

组件是有周期

componentWillMount 当要挂载

componentDidMount 挂载上时

componentWillUnmount 摧毁时

componentWillReceiveProps 当传来的 props 变化时

shouldComponentUpdate 返回 boolean

componentWillUpdate 当组件要更新前

componentDidUpdate 当组件更新完

React 一次状态更新,一共分为 2 个阶段、 4 个生命周期

2 个阶段:

  • render 阶段:包括 Diff 算法,计算出状态变化
  • commit 渲染阶段:ReactDOM 渲染器,将状态变化渲染在视图中

4 个生命周期:

  • Mount(第一次挂载)
  • Update(更新)
  • Unmount(卸载)
  • Error(子项发生错误)
生命周期函数所属阶段所属生命周期
constructorRender 阶段Mount
componentWillReceivePropsRender 阶段Update
getDerivedStateFromPropsRender 阶段并存于 Moun、Update
getDerivedStateFromErrorRender 阶段Error
shouldComponentUpdateRender 阶段Update
componentWillMountRender 阶段Mount
componentWillUpdateRender 阶段Update
renderRender 阶段并存于 Mount、Update
componentDidMountCommit 阶段Mount
getSnapshotBeforeUpdateCommit 阶段Update
componentDidUpdateCommit 阶段Update
componentWillUnmountCommit 阶段Unmount
componentDidCatchCommit 阶段Error

现在生命周期都没人考了,为什么?大家都用 函数式组件来写,状态的话由 hook 来管理

为什么?写起来简单,不用写不必要的生命周期

组件渲染:

constructor-componentWillMount-render-componentDidMount

组件卸载:

componentDidUnmount

调用 this.setState

shouldComponentUpdate-componentWillUpdate-render-componentDidUpdate

props 变化

componentWillReceiveProps-shouldComponentUpdate-componentWillUpdate-render-componentDidUpdate(比调用 this.setState 多了 componentWillReceiveProps)

image-20210429143319567

这些场景,我们同样需要在 React Hook 中予以解决。React 为Class component设计了一大堆生命周期函数:

  • 在实际的项目开发中用的比较频繁的,譬如渲染后期的:componentDidMountcomponentDidUpdatecomponentWillUnmount
  • 很少被使用的渲染前期钩子componentWillMountcomponentWillUpdate
  • 一直以来被滥用且有争议的componentWillReceiveProps和最新的getDerivedStateFromProps
  • 用于性能优化的shouldComponentUpdate

React 16.3 版本已经明确了将在 17 版本中废弃componentWillMountcomponentWillUpdatecomponentWillReceiveProps这三个生命周期函数。设计用来取代componentWillReceivePropsgetDerivedStateFromProps也并不被推荐使用

总的来说

  1. 挂载时调用 constructor,更新时不调用
  2. 更新时调用 shouldComponentUpdate 和 getSnapshotBeforeUpdate,挂载时不调用
  3. shouldComponentUpdate 在 render 前调用,getSnapshotBeforeUpdate 在 render 后调用
  4. 请求放在 componentDidMount 里
    • commit 阶段调用

参考资料