React生命周期
组件的生命周期可分成三个状态:
- Mounting(挂载):已插入真实 DOM
- Updating(更新):正在被重新渲染
- Unmounting(卸载):已移出真实 DOM
挂载
当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:
constructor()
: 在 React 组件挂载之前,会调用它的构造函数。getDerivedStateFromProps()
: 在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。render()
: render() 方法是 class 组件中唯一必须实现的方法。componentDidMount()
: 在组件挂载后(插入 DOM 树中)立即调用。
render() 方法是 class 组件中唯一必须实现的方法,其他方法可以根据自己的需要来实现。
这些方法的详细说明,可以参考官方文档。
更新
每当组件的 state 或 props 发生变化时,组件就会更新。
当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下:
getDerivedStateFromProps()
: 在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。根据 shouldComponentUpdate() 的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。shouldComponentUpdate()
:当 props 或 state 发生变化时,shouldComponentUpdate() 会在渲染执行之前被调用。render()
: render() 方法是 class 组件中唯一必须实现的方法。getSnapshotBeforeUpdate()
: 在最近一次渲染输出(提交到 DOM 节点)之前调用。componentDidUpdate()
: 在更新后会被立即调用。
render() 方法是 class 组件中唯一必须实现的方法,其他方法可以根据自己的需要来实现。
这些方法的详细说明,可以参考官方文档。
卸载
当组件从 DOM 中移除时会调用如下方法:
componentWillUnmount()
: 在组件卸载及销毁之前直接调用。- 这些方法的详细说明,可以参考官方文档。
React的生命周期中常用的有:
constructor,负责数据初始化。
render,将jsx转换成真实的dom节点。
componentDidMount,组件第一次渲染完成时触发。
componentDidUpdate,组件更新完成时触发。
componentWillUnmount,组件销毁和卸载时触发。
不常用的有:
getDerivedStateFromProps,更新state和处理回调。
shouldComponentUpdate,用于性能优化。
getSnapshotBeforeUpdate,替代了componentWillUpdate。
补充
constructor(): 完成了数据的初始化。注意:只要使用了constructor()就必须写super(),否则this指向会出错。
render(): render()函数会将jsx生成的dom插入到目标节点中。在每次组件更新时,react通过diff算法比较更新前和更新之后的dom节点,找到最小的有差异的dom位置并更新,花费最小的开销。
componentDidMount(): 组件第一次渲染完成,此时dom节点已经生成,在这里调用接口请求,返回数据后使用setState()更新数据后重新渲染。
componentDidUpdate(prevProps,prevState): 组件更新完成。每次react重新渲染之后都会进入这个生命周期,可以拿到更新之前的props和state。
componentWillUnmount(): 在这个生命周期完成组件的数据销毁和卸载,移除所有的定时器和监听。
getDerivedStateFromProps(nextProps,prevState): 代替老版的componentWillReceiveProps()。官方将更新state与触发回调重新分配到了componentWillReceiveProps()中,让组件整体的更新逻辑更加清晰,并且在当前生命周期中,禁止使用this.props,强制让开发者们通过比较nextProps和PrevState去保证数据的正确行为。
shouldComponentUpdate(): return true可以渲染,return false不重新渲染。
为什么会出现这个SCU生命周期?主要用于性能优化。也是唯一可以控制组件渲染的生命周期,在setState之后state发生改变组件会重新渲染,在当前生命周期内return false会阻止组件的更新。因为react中父组件重新渲染导致子组件也重新渲染,这时在子组件的当前生命周期内做判断是否真的需要重新渲染。
getSnapshotBeforeUpdate(prevProps,prevState): 代替componentWillUpdate(),核心区别在于getSnapshotBeforeUpdate()中读取到的dom元素状态是可以保证和componentDidUpdate()中的一致。