共计 2314 个字符,预计需要花费 6 分钟才能阅读完成。
号外号外!走过路过千万不要错过!
截止目前为止 React 曾经公布了 v16.12.0
版本, React 生命周期也是日常开发抬头不见,低头见的狗子,惋惜狗子它变了。
扭转起因
v16.3 版本之前,React 中的更新操作是同步的,这可能会导致性能问题。
举个例子,如果有一个宏大的模块外面嵌套超级多的组件,一旦最顶部的 render 办法执行了,而后顺次执行组件的 render 办法,直到最底层组件。这个过程会导致主线程卡主。
官网为了解决这个问题,因而引入了 React Fiber,其解决思路是分片执行,一个更新过程被分为两个阶段(Phase):第一个阶段 Reconciliation Phase 和第二阶段 Commit Phase。
在第一阶段 Reconciliation Phase,React Fiber 会找出须要更新哪些 DOM,这个阶段是能够被打断的;然而到了第二阶段 Commit Phase,那就一鼓作气把 DOM 更新完,绝不会被打断。
而这两个阶段也对应到不同的生命周期:
第一阶段
- componentWillMount
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
第二阶段
- componentDidMount
- componentDidUpdate
- componentWillUnmount
能够看看这个例子:Fiber vs Stack Demo
变更比照
以前:
当初(v16.3):
比照高低两张图,发现 React 废除了以下办法:
- componentWillMount
- componentWillReceiveProps
- componentWillUpdate
这里须要阐明一下:为了做到版本版本兼容 减少 UNSAFE_componentWillMount
,UNSAFE_componentWillReceiveProps
和 UNSAFE_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 新旧生命周期的思考了解