React生命周期
一、简介
React生命周期指的是组件从创建到卸载的整个过程,每个过程都有对应的钩子函数,它主要有以下几个阶段:
- 挂载阶段:组件实例被创建和插入Dom树的过程;
- 更新阶段:组件被重新渲染的过程;
- 卸载阶段:组件从Dom树中被删除的过程。
二、挂载阶段
组件实例被创建并插入 DOM 中时所触发的一些钩子函数。
1. constructor(props,context)
constructor()中完成了React数据的初始化,它接受两个参数:props和context,当 想在函数内部使用这两个参数时,需使用super()传入这两个参数。只会执行一次
2. componentWillMount()
组件初始化时只调用,以后组件更新不调用,整个生命周期只调用一次,此时可以修改state。
3. componentDidMount()
在组件挂载后(插入 DOM 树中)立即调用。只会执行一次
三、更新阶段
执行时机:1. setState() 2. forceUpdate()3. 组件接收到新的 props,以上三者任意一种变化,组件就会重新渲染。
1. shouldComponentUpdate()
返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。可以在你确认不需要更新组件时使用。此函数会在渲染执行之前被调用。
2. getDerivedStateFromProps()
在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。根据 shouldComponentUpdate() 的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。
3. componentWillReceiveProps(nextProps, prevState) (React16后废弃)
组件初始化时不调用,在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。
4. getDerivedStateFromProps(nextProps, prevState)
代替componentWillReceiveProps()。老版本中的componentWillReceiveProps()方法判断前后两个 props 是否相同,如果不同再将新的 props 更新到相应的 state 上去。这样做一来会破坏 state 数据的单一数据源,导致组件状态变得不可预测,另一方面也会增加组件的重绘次数。组件更新再次执行
5. render()
render函数会插入jsx生成的dom结构,react会生成一份虚拟dom树,在每一次组件更新时,比较新旧DOM树,找到最小的有差异的DOM节点,并重新渲染。注意:组件更新再次执行,不能使用setState(),否则会造成死循环。
6. getSnapshotBeforeUpdate()
在最近一次渲染输出(提交到 DOM 节点)之前调用。
7. componentDidUpdate()
在组件完成更新后立即调用。在初始化时不会被调用。
四、卸载阶段
当组件从页面中消失时,触发组件卸载。
1. componentWillUnmount
在组件卸载及销毁之前直接调用。
五、总结
- 第一次渲染页面时所触发的生命周期为:constructor(数据初始化)——>componentWillMount(初始化完成)——>render(渲染页面)——>componentDidMount(页面渲染完成)——>componentWillUnmount(页面卸载)
- 接口请求、事件监听和绑定定时器等通常放到componentDidMount()钩子函数中,此时组件已经挂载,DOM树也构建完毕。而移除事件监听和清除定时器要放到componentWillUnmount()钩子函数中,避免发生内存泄露。
- 大部分情况下 componentWillReceiveProps 生命周期函数是没用的,因为子组件中每次传递过来的this.props对象其实和componentWillReceiveProps的nextProps是一样的,都是最新的。
- 数据更新的话第一步是shouldComponentUpdate确认是否要更新数据,当这个函数返回的是true的时候才会进行更新,并且这个函数可以声明两个参数nextProps和nextState;当返回false时页面不更新。