生命周期 用户可以操作dom_React 生命周期的打怪升级之路

4eed8f91993492d38036cc43fdfe8f4c.png
号外号外!走过路过千万不要错过!

截止目前为止 React 已经发布了 v16.12.0 版本, React 生命周期也是日常开发低头不见,抬头见的狗子,可惜狗子它变了。

改变原因

v16.3 版本之前, React 中的更新操作是同步的,这可能会导致性能问题。

举个例子,假如有一个庞大的模块里面嵌套超级多的组件,一旦最顶部的 render 方法执行了,然后依次执行组件的 render 方法,直到最底层组件。这个过程会导致主线程卡主。

官方为了解决这个问题,因此引入了 React Fiber,其解决思路是分片执行,一个更新过程被分为两个阶段(Phase):第一个阶段 Reconciliation Phase 和第二阶段 Commit Phase。

在第一阶段 Reconciliation Phase,React Fiber 会找出需要更新哪些 DOM,这个阶段是可以被打断的;但是到了第二阶段 Commit Phase,那就一鼓作气把 DOM 更新完,绝不会被打断。

而这两个阶段也对应到不同的生命周期:

第一阶段

  • componentWillMount
  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate

第二阶段

  • componentDidMount
  • componentDidUpdate
  • componentWillUnmount

可以看看这个例子:Fiber vs Stack Demo

变更对比

以前:

d04d0fc188801688dc0d6d674b2ff85b.png

现在( v16.3 ):

c871b67e0b36bc050cb5b91b5974e6db.png

对比上下两张图,发现 React 废弃了以下方法:

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

这里需要说明一下:为了做到版本版本兼容 增加 UNSAFE_componentWillMount,UNSAFE_componentWillReceivePropsUNSAFE_componentWillUpdate方法,新旧方法都能使用,但使用旧方法,开发模式下会有红色警告,在 React v17 更新时会彻底废弃。

新增了方法如下:

  • getDerivedStateFromProps
  • getSnapshotBeforeUpdate

阶段梳理

下面从三个阶段(挂载、更新、卸载)梳理下生命周期方法。

92205e8d85fdbc7dba371d9e1739ccdb.png

constructor 构造函数

执行的生命周期方法,如果需要做一些初始化操作,比如初始化 state, 反正则无需为 React 组件实现构造函数。

getDerivedStateFromProps

当组件实例化的时候,这个方法替代了 componentWillMount(),而当接收到新的 props 时,该方法替代了 componentWillReceiveProps() 和 componentWillUpdate()。

static getDerivedStateFromProps(nextProps, prevState)

其中 v16.3 版本中 re-rendering 之后此方法不会被调用,而 v16.4 版本中 re-rendering 之后都会调用此方法,这意味及时的 props 未发生改变,一旦父组件发生 re-rendering 那么子组件的该方法依然会被调用。

componentWillMount/UNSAVE_componentWillMount (即将废弃)

部分同学日常会把数据请求放在该方法内,以便于快速获取数据并展现,我的理解再怎么快,也快不过首次 render,并且 React Fiber 执行机制的原因,会导致该方法被执行多次,这也意味着接口被请求多次。因此该方法在 v17 版本以后将被彻底废弃。

componentDidMount

在组件挂载完成后调用,且全局只调用一次。可以在这里使用 refs,获取真实 dom 元素。该钩子内也可以发起异步请求,并在异步请求中可以进行 setState。

componentWillReceiveProps/UNSAFE_componentWillReceiveProps (即将废弃)

被 getDerivedStateFromProps 方法取代。

shouldComponentUpdate

每次调用 setState 后都会调用 shouldComponentUpdate 判断是否需要重新渲染组件。默认返回 true,需要重新 render。返回 false 则不触发渲染。在比较复杂的应用里,有一些数据的改变并不影响界面展示,可以在这里做判断,优化渲染效率。

componentWillUpdate

依旧是 React Fiber 执行机制的原因,在该方法记录 DOM 状态就不在准确了。

getSnapshotBeforeUpdate

触发该方法的实际,是在更新 DOM 之前的一瞬间,比 componentWillUpdate 记录的 DOM 状态更为精确。

componentDidUpdate

除了首次 render 之后调用 componentDidMount,其它 render 结束之后都是调用 componentDidUpdate。

componentWillUnmount

组件被卸载的时候调用。一般在 componentDidMount 里面注册的事件需要在这里删除。

总结

由于 React 同步更新组件的原因,会引起性能问题,造成主线程卡死,因此引入 React Fiber 对核心算法的一次重新实现。 紧接着发现, React Fiber 会让部分生命周期方法行多次,而废除这部分方法,引入新方法。

参考文章:

React Fiber 是什么

React v16.3 之后的组件生命周期函数

浅谈 React Fiber 及其对 lifecycles 造成的影响

讲讲今后 React 异步渲染带来的生命周期变化

React 新旧生命周期的思考理解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值