React16 Lifecycle

229 阅读3分钟

挂载阶段:React15 vs React16.3

React15

constructor()
componentWillMount()
render()
componentDidMount()

React16.3

constructor()
getDerivedStateFromProps()
render()
componentDidMount()

对比可见,废弃了componentWillMount方法,新增了getDerivedStateFromProps方法

React16对render方法进行了一些改进。React16之前render方法必须返回单个元素,而React16允许我们返回元素数组和字符串。

getDerivedStateFromProps在挂载和更新阶段都会出现。

static getDerivedStateFromProps(props, state)

  1. getDerivedStateFromProps是一个静态方法,不能访问组件实例
  2. 来自父组件的props和组件自身的state
  3. props传入的内容不需要影响到你的state,则需要返回一个null

getDerivedStateFromProps方法对state的更新动作并非“覆盖”式的更新,而是针对某个属性的定向更新。

更新阶段:React15 vs React16

React15

componentWillReceiveProps()
shouldComponentUpdate()
componentWillUpdate()
render()
componentDidUpdate()

React16.3

getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
更新阶段,在React16.3中只有父组件更新才会触发getDerivedStateFromProps生命周期。而在React16.4中,任何因素触发的组件更新流程都会触发getDerivedStateFromProps。

getSnapshotBeforeUpdate(prevProps, prevState)

A snapshot value (or null) should be returned.

  1. getSnapshotBeforeUpdate的返回值会作为第三个参数给到componentDidUpdate,它的执行时机是在render方法后,真实DOM更新前。

  2. 同时获取到更新前的真实DOM和更新前后的state和props的信息

卸载阶段:React15与React16 无变化

React LifeCycle Diagram

初识Fiber

Fiber是React16对React核心算法的一次重写

Fiber会使原本同步的渲染过程编程异步的

触发组件更新,React会构建新的虚拟DOM树,通过与上一次的虚拟DOM树进行diff,实现对DOM的定向更新,这个过程是一个递归的过程。同步渲染的递归调用栈非常深,只有最底层的调用返回了,整个渲染过程才会开始逐层返回,这个漫长且不可打断的更新过程将会带来用户体验层面的巨大风险,同步渲染一旦开始便会牢牢抓住主线程不放,直到递归彻底完成。在这个过程中浏览器没有办法处理任何渲染之外的事情,会进入无法处理用户交互的状态,因此渲染时间稍微长一点,页面就会进入卡顿。Fiber会将一个大的更新任务拆解为许多小任务,每当执行完一个小任务的时候,渲染线程都会把主线程交回去,看看有没有优先级更高的工作要处理,确保不会出现其他任务被卡,进而避免同步渲染带来的卡顿。在这个过程中,渲染线程不再一去不回头,而是可以被打断的,这就是异步渲染。

Fiber架构的重要特征就是可以被打断的异步渲染模式

React16的生命周期被分为了render和commit两个阶段

“Render 阶段”
纯净且不包含副作用。可能会被 React 暂停,中止或重新启动。

“Pre-commit 阶段”
可以读取 DOM。

“Commit 阶段”
可以使用 DOM,运行副作用,安排更新。

Render阶段可以被打断,而commit阶段总是同步执行的