生命周期详见 react v16.12 官网
可以生命周期图谱作为速查表
挂载
当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:
- constructor()
- static getDerivedStateFromProps()
- render()
- componentDidMount()
getDerivedStateFromProps 是 16.3 新加入的 API
componentWillMount() 即将过时,不要使用。
componentWillMount() 的代码大多数情况,尤其是费时的,异步的操作都可以直接移去 componentDidMount()。少部分情况如初始化状态设置,可以移去 constructor()。
componentWillMount() 有使用陷阱,比方说在此函数里获取数据,想避免首页白屏或者空渲染状态。但是行不通的,因为 React 总是在 componentWillMount 之后立即执行 render,不会管 componentWillMount 内是否执行完毕。所以解决思路应该就是初始化时设好骨架屏或者显示好占位元素,然后在 componentDidMount 里执行异步获取数据操作。
并且如果有订阅事件的需要也放到 componentDidMount ,因为在 async render 的情况下,componentWillMount 会触发多次。
更新
当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下:
- static getDerivedStateFromProps()
- shouldComponentUpdate()
- render()
- getSnapshotBeforeUpdate()
- componentDidUpdate()
componentWillUpdate() 与 componentWillReceiveProps() 即将过时,不要使用。
注意,componentWillReceiveProps() 过时,但是替代它可以使用下面的做法,相当于 componentWillReceiveProps() 拆分成两处,使派生状态更容易预测。
static getDerivedStateFromProps(nextProps, prevState) {
// 该方法内禁止访问 this
if (nextProps.defaultValue !== prevState.something) {
// 通过对比nextProps和prevState,返回一个用于更新状态的对象
return { something: nextProps.defaultValue };
}
// 不需要更新状态,返回null
return null;
}
// 并且仍想通过更新时的 this.props 做一些有副作用的事情,可以使用 componentDidUpdate
componentDidUpdate(prevProps, prevState, snapshot) {
if(this.props.email){
// 例如dispatch action,或者做动画那样的副作用的事情。
}
}
卸载
当组件从 DOM 中移除时会调用如下方法:
- componentWillUnmount()
错误处理
当渲染过程,生命周期,或子组件的构造函数中抛出错误时,会调用如下方法:
- static getDerivedStateFromError()
- componentDidCatch()