目录
挂载:在组件实例被创建并插入到dom中时,生命周期调用顺序如下
更新:当组件的 props 或 state 发生变化时会触发更新。
错误处理:当渲染过程,生命周期,或子组件的构造函数中抛出错误时
重新学习理解react生命周期,本文主要参考链接:
React新生命周期--getDerivedStateFromProps - 简书
这里我没有将新旧生命周期分开写,后面标注的可以用但是不建议使用的就是被新生命周期替换的旧生命周期。图一是旧生命周期,图二是新生命周期。
首先生命周期分为三个阶段:
挂载:已经插入真实dom
渲染(更新):正在被重新渲染
卸载:已经移出真实dom
一、挂载:在组件实例被创建并插入到dom中时,生命周期调用顺序如下
旧生命周期:
1.constructor(props)
2.componentWillMount()-------------可以用但是不建议使用
3.render()
4.componentDidMount()
新生命周期:
- constructor(props)
- static getDerivedStateFromProps(props,state)--替代了
componentWillReceiveProps
- render()
- componentDidMount()
(1)constructor
数据的初始化。
接收props和context,当想在函数内使用这两个参数需要在super传入参数,当使用constructor时必须使用super,否则可能会有this的指向问题,如果不初始化state或者不进行方法绑定,则可以不为组件实现构造函数;
避免将 props 的值复制给 state!这是一个常见的错误:
constructor(props) {
super(props);
// 不要这样做
this.state = { color: props.color };
}
如此做毫无必要(可以直接使用 this.props.color
),同时还产生了 bug(更新 prop 中的 color
时,并不会影响 state)。
(2)componentWillMount
在挂载之前也就是render之前被调用。
在服务端渲染唯一会调用的函数,代表已经初始化数据但是没有渲染dom,因此在此方法中同步调用 setState()
不会触发额外渲染。
(3)getDerivedStateFromProps
从props获取state。
替代了componentWillReceiveProps,
此方法适用于罕见的用例,即 state 的值在任何时候都取决于 props。
在初始挂载和后续更新时都会被调用,返回一个对象更新state,如果返回null就不更新;
如果props传入的内容不需要影响到你的state,那么就需要返回一个null,这个返回值是必须的,所以尽量将其写到函数的末尾。
static getDerivedStateFromProps(nextProps, prevState) {
const {type} = nextProps;
// 当传入的type发生变化的时候,更新state
if (type !== prevState.type) {
return {
type,
};
}
// 否则,对于state不进行任何操作
return null;
}
老版本中的componentWillReceiveProps()方法判断前后两个 props 是否相同,如果不同再将新的 props 更新到相应的 state 上去。这样做一来会破坏 state 数据的单一数据源,导致组件状态变得不可预测,另一方面也会增加组件的重绘次数。
这两者最大的不同就是:
在 componentWillReceiveProps 中,我们一般会做以下两件事,一是根据 props 来更新 state,二是触发一些回调,如动画或页面跳转等。
- 在老版本的 React 中,这两件事我们都需要在 componentWillReceiveProps 中去做。
- 而在新版本中,官方将更新 state 与触发回调重新分配到了 getDerivedStateFromProps 与 componentDidUpdate 中,使得组件整体的更新逻辑更为清晰。而且在 getDerivedStateFromProps 中还禁止了组件去访问 this.props,强制让开发者去比较 nextProps 与 prevState 中的值,以确保当开发者用到 getDerivedStateFromProps 这个生命周期函数时,就是在根据当前的 props 来更新组件的 state,而不是去做其他一些让组件自身状态变得更加不可预测的事情。