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(子项发生错误)
生命周期函数 | 所属阶段 | 所属生命周期 |
---|---|---|
constructor | Render 阶段 | Mount |
componentWillReceiveProps | Render 阶段 | Update |
getDerivedStateFromProps | Render 阶段 | 并存于 Moun、Update |
getDerivedStateFromError | Render 阶段 | Error |
shouldComponentUpdate | Render 阶段 | Update |
componentWillMount | Render 阶段 | Mount |
componentWillUpdate | Render 阶段 | Update |
render | Render 阶段 | 并存于 Mount、Update |
componentDidMount | Commit 阶段 | Mount |
getSnapshotBeforeUpdate | Commit 阶段 | Update |
componentDidUpdate | Commit 阶段 | Update |
componentWillUnmount | Commit 阶段 | Unmount |
componentDidCatch | Commit 阶段 | Error |
现在生命周期都没人考了,为什么?大家都用 函数式组件来写,状态的话由 hook 来管理
为什么?写起来简单,不用写不必要的生命周期
组件渲染:
constructor-componentWillMount-render-componentDidMount
组件卸载:
componentDidUnmount
调用 this.setState
shouldComponentUpdate-componentWillUpdate-render-componentDidUpdate
props 变化
componentWillReceiveProps-shouldComponentUpdate-componentWillUpdate-render-componentDidUpdate(比调用 this.setState 多了 componentWillReceiveProps)
这些场景,我们同样需要在 React Hook 中予以解决。React 为Class component
设计了一大堆生命周期函数:
- 在实际的项目开发中用的比较频繁的,譬如渲染后期的:
componentDidMount
、componentDidUpdate
、componentWillUnmount
; - 很少被使用的渲染前期钩子
componentWillMount
、componentWillUpdate
; - 一直以来被滥用且有争议的
componentWillReceiveProps
和最新的getDerivedStateFromProps
; - 用于性能优化的
shouldComponentUpdate
;
React 16.3 版本已经明确了将在 17 版本中废弃componentWillMount
、componentWillUpdate
和componentWillReceiveProps
这三个生命周期函数。设计用来取代componentWillReceiveProps
的getDerivedStateFromProps
也并不被推荐使用
总的来说
- 挂载时调用 constructor,更新时不调用
- 更新时调用 shouldComponentUpdate 和 getSnapshotBeforeUpdate,挂载时不调用
- shouldComponentUpdate 在 render 前调用,getSnapshotBeforeUpdate 在 render 后调用
- 请求放在 componentDidMount 里
- commit 阶段调用