1.生命周期调用的顺序
挂载:
constructor
:初始化state
和方法绑定,使用this.state
给state
赋值getDerivedStateFromProps()
|UNSAFE_componentWillMount()
(即将被废弃):会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新任何内容。render()
:渲染组件(如果shouldComponentUpdate()
返回false,则不会调用render()
)componentDidMount()
:执行网络请求获取数据,添加订阅
更新:(当state改变之后引发修改UI,通过的生命周期函数)
getDerivedStateFromProps()
|UNSAFE_componentWillReceiveProps
(即将被废弃) 组件接收到新props调用shouldComponentUpdate
:当组件接收到新属性,或者组件的状态发生改变时触发。组件首次渲染时并不会触发,性能优化getSnapshotBeforeUpdate()
:返回值将作为componentDidUpdate()
的第三个参数“snapshot”
参数传递。否则此参数将为undefined
。UNSAFE_componentWillUpdate()
(即将被废弃):组件更新调用,可以修改state值comonentDidUpdate
:执行网络请求,当props
未改变则不会触发该函数,也就不会发送网络请求(当shouldComponentUpdate()
返回false,则不会调用componentDidUpdate()
)
销毁:
componentWillUnmount()
:组件卸载及销毁之前调用(取消订阅,清楚定时器,取消网络请求)
2.不常用的生命周期函数
静态方法和实例方法
静态方法:直接挂载在class类上,或者使用新的关键字static,实例无法直接访问该方法。
实例方法:挂载在this上或者挂载在prototype上,class类不能直接访问该方法,使用new关键字实例化之后,实例可以访问该方法。
shouldComponentUpdate()
:为性能优化存在static getDerivedStateFromProps()
:返回一个对象来更新 state,如果返回 null 则不更新任何内容。getSnapshotBeforeUpdate()
:会在组件即将挂载时调用。用途:有一些状态,比如网页滚动位置,我不需要它持久化,只需要在组件更新以后能够恢复原来的位置即可。
3.捕获错误的生命周期函数
static getDerivedStateFromError()
:在后代组件抛出错误后被调用。 它将抛出的错误作为参数,并返回一个值以更新 statecomponentDidCatch()
:在后代组件抛出错误后被调用。 它接收两个参数:
error —— 抛出的错误。
info —— 带有 componentStack key 的对象,其中包含有关组件引发错误的栈信息。
4.过时的生命周期函数(V17之后就会被废弃,所以尽量不要使用)
UNSAFE_componentWillMount()
:UNSAFE_componentWillReceiveProps()
:UNSAFE_componentWillUpdate()
:
为什么要废除掉这些生命周期呢?
react官网解释:生命周期方法经常被误解和巧妙地误用
react将会提出Fiber渲染机制。将react diff的过程改为了异步。
原理是Fiber把任务切成很小的片,每执行一片就把控制权交还给主线程,待主线程忙完手头的活再来执行剩下的任务。当然如果某一片的执行时间就很长(比如死循环),那就没主线程什么事了,该崩溃崩溃。
主要影响就是挂载和更新之前的生命周期都变的不可靠了。因为Reconciliation这个过程有可能暂停然后继续执行,所以挂载和更新之前的生命周期钩子就有可能不执行或者多次执行,它的表现是不可预期的。
生命周期一旦被打断,下次恢复的时候又会再跑一次之前的生命周期,因此componentWillMount,componentWillReceiveProps, componentWillUpdate都不能保证只在挂载/拿到props/状态变化的时候刷新一次了,所以这三个方法被标记为不安全。