React 生命周期的打怪升级之路

号外号外!走过路过千万不要错过!javascript

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

改变缘由

v16.3 版本以前, React 中的更新操做是同步的,这可能会致使性能问题。react

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

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

在第一阶段 Reconciliation Phase,React Fiber 会找出须要更新哪些 DOM,这个阶段是能够被打断的;可是到了第二阶段 Commit Phase,那就一气呵成把 DOM 更新完,毫不会被打断。算法

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

第一阶段异步

  • componentWillMount
  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate

第二阶段函数

  • componentDidMount
  • componentDidUpdate
  • componentWillUnmount

能够看看这个例子:Fiber vs Stack Demopost

变动对比

之前:

如今( v16.3 ):

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

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

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

新增了方法以下:

  • getDerivedStateFromProps
  • getSnapshotBeforeUpdate

阶段梳理

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

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 新旧生命周期的思考理解

相关文章
相关标签/搜索