自从React发布Fiber以后,更新速度突飞猛进,而生命周期也随之改变,虽然原有的一些生命周期函数面临废弃,但理解其背后更新的机制也是一种学习html
在这里根据官方文档以及社区上其余优秀的文章进行一个对于生命周期的总结,大体上分为如下三个模块react
新的生命周期增长了static getDerivedStateFromProps()以及getSnapshotBeforeUpdate(),废弃了原有的componentWillMount()、componentWillUpdate()以及componentWillReceiveProps(),
分别如如下图 安全
原生命周期: 框架
新生命周期(图引用自React v16.3以后的组件生命周期函数): 异步
做者一开始也喜欢在React的willMount函数中进行异步获取数据(认为这能够减小白屏的时间),后来发现其实应该在didMount中进行。函数
首先,分析一下二者请求数据的区别: 学习
componentWillMount获取数据:优化
didMount获取数据:this
很明显,在willMount中获取数据,能够节省时间(render函数和didMount函数的执行时间),可是为何咱们还要在didMount中获取数据spa
关于第一点,若是你想在服务端渲染时先完成数据的展现再一次性给用户,官方的推荐作法是用constructor代替willMount
从上面的生命周期的图中能够看出,被废弃的三个函数都是在render以前,由于fiber的出现,极可能由于高优先级任务的出现而打断现有任务致使它们会被执行屡次
另外的一个缘由则是,React想约束使用者,好的框架可以让人不得已写出容易维护和扩展的代码,这一点又是从何谈起,咱们能够重新增长以及即将废弃的生命周期分析入手
首先这个函数的功能彻底可使用componentDidMount和constructor来代替,异步获取的数据的状况上面已经说明了,而若是抛去异步获取数据,其他的便是初始化而已,这些功能均可以在constructor中执行,除此以外,若是咱们在willMount中订阅事件,但在服务端这并不会执行willUnMount事件,也就是说服务端会致使内存泄漏
因此componentWillMount彻底能够不使用,但使用者有时候不免由于各类各样的状况(如做者犯浑)在componentWillMount中作一些操做,那么React为了约束开发者,干脆就抛掉了这个API
在老版本的 React 中,若是组件自身的某个 state 跟其 props 密切相关的话,一直都没有一种很优雅的处理方式去更新 state,而是须要在 componentWillReceiveProps 中判断先后两个 props 是否相同,若是不一样再将新的 props 更新到相应的 state 上去。这样作一来会破坏 state 数据的单一数据源,致使组件状态变得不可预测,另外一方面也会增长组件的重绘次数。相似的业务需求也有不少,如一个能够横向滑动的列表,当前高亮的 Tab 显然隶属于列表自身的状态,但不少状况下,业务需求会要求从外部跳转至列表时,根据传入的某个值,直接定位到某个 Tab。 本段引用自React v16.3 版本新生命周期函数浅析及升级方案
为了解决这些问题,React引入了第一个新的生命周期
能够先看一下二者在使用上的区别:
原有的代码
新的代码
这样看彷佛没有什么改变,特别是当咱们把this,tabChange也放在didUpdate中执行时(正确作法),彻底没有不一样,但这也是咱们一开始想说的,React经过API来约束开发者写出更好的代码,而新的使用方法有如下的优势
与 componentWillReceiveProps 相似,许多开发者也会在 componentWillUpdate 中根据 props 的变化去触发一些回调。但不管是 componentWillReceiveProps 仍是 componentWillUpdate,都有可能在一次更新中被调用屡次,也就是说写在这里的回调函数也有可能会被调用屡次,这显然是不可取的。与 componentDidMount 相似,componentDidUpdate 也不存在这样的问题,一次更新中 componentDidUpdate 只会被调用一次,因此将原先写在 componentWillUpdate 中的回调迁移至 componentDidUpdate 就能够解决这个问题。 本段引用自React v16.3 版本新生命周期函数浅析及升级方案
另一种状况则是咱们须要获取DOM元素状态,可是因为在fiber中,render可打断,可能在willMount中获取到的元素状态极可能与实际须要的不一样,这个一般可使用第二个新增的生命函数的解决
getSnapshotBeforeUpdate(prevProps, prevState) // 返回的值做为componentDidUpdate的第三个参数
与willMount不一样的是, getSnapshotBeforeUpdate会在最终肯定的render执行以前执行,也就是能保证其获取到的元素状态与didUpdate中获取到的元素状态相同,这里官方提供了一段参考代码:
随着React Fiber的落地,许多功能都将开始改变,但本质上是换汤不换药,不少时候都是React为了开发者写出更好的代码而作的改变,固然这也是React的厉害之处,经过框架来约束开发者!