##### V16.3 之前 我们可以将生命周期分为三个阶段: - 挂载阶段 - 组件更新阶段 - 卸载阶段 分开来讲: 1. 挂载阶段 - `constructor`:避免将 props 的值复制给 state - `componentWillMount` - `render`:react 最重要的步骤,创建虚拟 dom,进行 diff 算法,更新 dom 树都在此进行 - `componentDidMount` 2. 组件更新阶段 - `componentWillReceiveProps` - `shouldComponentUpdate` - `componentWillUpdate` - `render` - `componentDidUpdate` 3. 卸载阶段 - `componentWillUnMount`  这种生命周期会存在一个问题,那就是当更新复杂组件的最上层组件时,调用栈会很长,如果在进行复杂的操作时,就可能长时间阻塞主线程,带来不好的用户体验,**Fiber** 就是为了解决该问题而生。 ##### V16.3 之后 **Fiber 本质上是一个虚拟的堆栈帧,新的调度器会按照优先级自由调度这些帧,从而将之前的同步渲染改成了异步渲染,在不影响体验的情况下去分段计算更新。** 对于异步渲染,分为两阶段: - `reconciliation`: - `componentWillMount` - `componentWillReceiveProps` - `shouldConmponentUpdate` - `componentWillUpdate` - `commit` - `componentDidMount` - `componentDidUpdate` 其中,`reconciliation` 阶段是可以被打断的,所以 `reconcilation` 阶段执行的函数就会出现多次调用的情况,显然,这是不合理的。 所以 V16.3 引入了新的 API 来解决这个问题: 1. `static getDerivedStateFromProps`: 该函数在**挂载阶段和组件更新阶段**都会执行,即**每次获取新的`props` 或 `state` 之后都会被执行**,**在挂载阶段用来代替`componentWillMount`**;在组件更新阶段配合 `componentDidUpdate`,可以覆盖 `componentWillReceiveProps` 的所有用法。 同时它是一个静态函数,所以函数体内不能访问 `this`,会根据 `nextProps` 和 `prevState` 计算出预期的状态改变,返回结果会被送给 `setState`**,**返回 `null` 则说明不需要更新 `state`,并且这个返回是**必须的**。 2. `getSnapshotBeforeUpdate`: 该函数会在 **`render` 之后, DOM 更新前**被调用,用于读取最新的 DOM 数据。 返回一个值,**作为 `componentDidUpdate` 的第三个参数**;配合 `componentDidUpdate`, 可以覆盖`componentWillUpdate` 的所有用法。 注意:V16.3 中只用在组件挂载或组件 `props` 更新过程才会调用,即如果是因为自身 setState 引发或者forceUpdate 引发,而不是由父组件引发的话,那么`static getDerivedStateFromProps`也不会被调用,在 V16.4 中更正为都调用。 即更新后的生命周期为: 1. 挂载阶段 - `constructor` - `static getDerivedStateFromProps` - `render` - `componentDidMount` 2. 更新阶段 - `static getDerivedStateFromProps` - `shouldComponentUpdate` - `render` - `getSnapshotBeforeUpdate` - `componentDidUpdate` 3. 卸载阶段 - `componentWillUnmount`  更多请看 [深入 React 生命周期](https://github.com/sisterAn/blog/issues/34)