React 生命周期
// React 15
componentWillReceiveProps();
shouldComponentUpdate();
componentWillMount();
componentWillUpdate();
componentDidUpdate();
componentDidMount();
render();
componentWillUnmount();
组件的更新分为两种:一种是由父组件更新触发的更新;另一种是组件自身调用自己的 setState 触发的更新。
componentReceiveProps 并不是由 props 的变化触发的,而是由父组件的更新触发的,这个结论,请你谨记。
React 16.3 的生命周期

React 15 生命周期和 React 16.3 生命周期在挂载阶段的主要差异在于,废弃了 componentWillMount,新增了 getDerivedStateFromProps。
消失的 componentWillUpdate 与新增的 getSnapshotBeforeUpdate
区别在于 getSnapshotBeforeUpdate 的返回值会作为第三个参数给到 componentDidUpdate。它的执行时机是在 render 方法之后,真实 DOM 更新之前。在这个阶段里,我们可以同时获取到更新前的真实 DOM 和更新前后的 state&props 信息。
这个生命周期的设计初衷,是为了“与 componentDidUpdate 一起,涵盖过时的 componentWillUpdate 的所有用例”(引用自 React 官网)。
为什么要去除掉 componentWillUpdate
因为 react 15 是同步进行渲染,同步渲染的递归栈是非常深的,而且不能打断,这样就很容易一直占据着主线程,直到递归结束释放主线程**。在这个过程中,浏览器没有办法处理任何渲染之外的事情,会进入一种无法处理用户交互**的状态。因此若渲染时间稍微长一点,页面就会面临卡顿甚至卡死的风险。
在 Fiber 机制下,render 阶段是允许暂停、终止和重启的。当一个任务执行到一半被打断后,下一次渲染线程抢回主动权时,这个任务被重启的形式是“重复执行一遍整个任务”而非“接着上次执行到的那行代码往下走”。这就导致 render 阶段的生命周期都是有可能被重复执行的。
我们再来看看 React 16 打算废弃的是哪些生命周期:
- componentWillMount;
- componentWillUpdate;
- componentWillReceiveProps。
这些生命周期的共性,就是它们都处于 render 阶段,都可能重复被执行,而且由于这些 API 常年被滥用,它们在重复执行的过程中都存在着不可小觑的风险。
React 团队给出的这篇文章 就帮助大家规避“误操作”来说是绰绰有余的。