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