# React生命周期分析
在V16版本中引入了Fiber机制。这个机制在一定程度上影响了部分生命周期的调用,并且引入了新的2个API来解决问题。
在之前的版本中,如果你拥有一个很复杂的复合组件,然后改动了最上层组件的state,那么调用栈可能会很长
调用栈过长,再加上中间进行了复杂的操作,就可能导致长时间阻塞主线程,带来不好的用户体验。Fiber就是为了解决该问题而生。
Fiber本质上是一个虚拟的堆栈帧,新的调度器会按照优先级自由调度这些帧,从而将之前的额同步渲染改成异步渲染,在不影响体验的情况下去分段计算更新。
对于如何区别优先级,React有自己的一套逻辑。对于动画这种实时性很高的东西,也就是
16ms
必须渲染一次保证不卡顿的情况下,Reac会每16ms(以内)
暂停一下更新,返回来继续渲染动画。
对于异步渲染,现在渲染有两个阶段:reconciliation
和commit
。前者过程是可以打断的,后者不能暂停,会一直更新界面直到完成。
# Reconciliation阶段
- componentWillMount
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
# Commit阶段
- componentDidMount
- componentDidUpdate
- componentWillUnmount
因为reconciliation
阶段是可以被打断的,所以reconciliation
阶段会执行的生命周期函数就可能会出现调用多次的情况,从而引起Bug。所以对于reconciliation
阶段调用的几个函数,除了shouldComponentUpdate
以外,其他都应该避免去使用,并且V16也引入了新的API来解决这个问题。
getDerivedStateFromProps
用于替换componentWillReceiveProps
,该函数会在初始化和update时被调用
class ExampleComponent extends React.Component {
state = {}
static getDerivedStateFromProps(nextProps, prevState) {
if (prevState.someMirroredValue !== nextProps.someValue) {
return {
derivedData: computeDerivedState(nextProps),
someMirroredValue: nextProps.someValue
};
}
// Return null to indicate no change to state.
return null;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
getSnapshotBeforeUpdate
用于代替componentWillUpdate
,该函数会在update
后的DOM更新前被调用,用于读取最新的DOM数据
# V16 生命周期函数用法建议
class ExampleComponent extends React.Component {
// 用于初始化 state
constructor() {}
// 用于替换 `componentWillReceiveProps` ,该函数会在初始化和 `update` 时被调用
// 因为该函数是静态函数,所以取不到 `this`
// 如果需要对比 `prevProps` 需要单独在 `state` 中维护
static getDerivedStateFromProps(nextProps, prevState) {}
// 判断是否需要更新组件,多用于组件性能优化
shouldComponentUpdate(nextProps, nextState) {}
// 组件挂载后调用
// 可以在该函数中进行请求或者订阅
componentDidMount() {}
// 用于获得最新的 DOM 数据
getSnapshotBeforeUpdate() {}
// 组件即将销毁
// 可以在此处移除订阅,定时器等等
componentWillUnmount() {}
// 组件销毁后调用
componentDidUnMount() {}
// 组件更新后调用
componentDidUpdate() {}
// 渲染组件函数
render() {}
// 以下函数不建议使用
UNSAFE_componentWillMount() {}
UNSAFE_componentWillUpdate(nextProps, nextState) {}
UNSAFE_componentWillReceiveProps(nextProps) {}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 新增的生命周期
新增的getDerivedStateFromProps
和getSnapshotBeforeUpdate
如果存在以前的willMount,willReceiveProps,willUpdate,会报警告
#
getDerivedStateFromProps
- 该方法是静态的,使用需要加上static
- 该方法返回值将会更新state(返回null不更新),这样我们可以将props的值返回更新state,那么所有状态都由state来维护
# getSnapshotBeforeUpdate
- 和以前的区别在于返回值将作为didUpdate的第三个参数