前言
如果将React的生命周期比喻成一只蚂蚁爬过一根吊绳,那么这只蚂蚁从绳头爬到绳尾,就会依次触动不同的卡片挂钩。在React每一个生命周期中,也有类似卡片挂钩的存在,我们把它称之为‘钩子函数’。那么在React的生命周期中,到底有哪些钩子函数?React的生命周期又是怎样的流程?今天我给大家来总结总结
React 生命周期流程图
如图,React生命周期主要包括三个阶段:初始化阶段、运行中阶段和销毁阶段,在React不同的生命周期里,会依次触发不同的钩子函数,下面我们就来详细介绍一下React的生命周期函数。
一、初始化阶段:
- getDefaultProps:获取实例的默认属性 getInitialState:获取每个实例的初始化状态
- componentWillMount:组件即将被装载、渲染到页面上
- render:组件在这里生成虚拟的DOM节点
- componentDidMount:组件真正在被装载之后[AJAX请求]
二、运行中状态:
- componentWillReceiveProps:组件将要接收到属性的时候调用
- shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回false,接收数据后不更新,阻止render调用,后面的函数不会被继续执行了)
- componentWillUpdate:组件即将更新不能修改属性和状态
- render:组件重新描绘
- componentDidUpdate:组件已经更新
三、销毁阶段:
- componentWillUnmount:组件即将销毁
一、初始化阶段
1、设置组件的默认属性
static defaultProps = {
name: 'sls',
age:23
};
//or
Counter.defaltProps={name:'sls'}
2、设置组件的初始化状态
constructor() {
super();
this.state = {number: 0}
}
3、componentWillMount()
组件即将被渲染到页面之前触发,此时组件中的方法和状态都已经可以正常访问了,所以可以进行开启定时器、向服务器发送请求等操作(为什么说此时可以发请求了呢? 因为接口返回可能会更新state,而此阶段的方法和state已经可以正常访问了,所以此阶段是可以调接口的)
4、render()
组件渲染,该钩子函数是每个组件要求必须写的,其余可以不写,唯独它不行,不然就会报错;
5、componentDidMount()
组件已经被渲染到页面中后触发:此时已经将虚拟DOM真正地挂载到了页面中,页面中有了真正的DOM的元素,可以进行DOM相关的操作
二、运行中阶段
1、componentWillReceiveProps(nextProps)
组件接收到属性时触发(一般用在子组件中,在子组件的render函数执行前获取新的props,从而更新子组件自己的state。 可以将子组件的数据请求放在这里进行执行,需要传的参数则从componentWillReceiveProps(nextProps)中获取。而不必将所有的请求都放在父组件中。于是该请求只会在该组件渲染时才会发出,从而减轻请求负担,举个例子就是说一个父组件,调用一个子组件(侧滑组件),侧滑组件(子组件的显示由visible属性控制,起初这个属性是通过父组件传给子组件的),当点击列表编辑时,调用一个方法,改变父组件中的visible值,由false => true,此时子组件如何获取最新的visible属性的?那就是通过该函数传入nextProps参数获得,该props就是最新的props,从而可以在该函数中进行一些页面逻辑控制
2、shouldComponentUpdate(newProps, newState)
当组件接收到新属性,或者组件的状态发生改变时触发。组件首次渲染时并不会触发
shouldComponentUpdate(newProps, newState) {
if (newProps.number < 5) return true;
return false
}
//该钩子函数可以接收到两个参数,新的属性和状态,返回true/false来控制组件是否需要更新。
一般我们通过该函数来优化性能:
1、一个React项目需要更新一个小组件时,很可能需要父组件更新自己的状态。而一个父组件的重新更新会造成它旗下所有的子组件重新执行render()方法,形成新的虚拟DOM,再用diff算法对新旧虚拟DOM进行结构和属性的比较,决定组件是否需要重新渲染;
2、无疑这样的操作会造成很多的性能浪费,所以我们开发者可以根据项目的业务逻辑,在shouldComponentUpdate()中加入条件判断,从而优化性能,
3、例如React中的就提供了一个PureComponent的类,当我们的组件继承于它时,组件更新时就会默认先比较新旧属性和状态,从而决定组件是否更新。值得注意的是,PureComponent进行的是浅比较,所以组件状态或属性改变时,都需要返回一个新的对象或数组
3、componentWillUpdate()
组件即将被更新时触发,如果上面的shouldComponentUpdate()返回false,将不会被调用。
4、componentDidUpdate(prevProps,prevState)
组件被更新完成后触发。页面中产生了新的DOM的元素,可以进行DOM操作,传入的prevProps和prevState是初始的props和state,这个时候已经二次render完了,所以不存在nextProps,this.props中已经是最新的数据了,所以想得到最新的属性值,直接通过this.props拿,这里的prevProps、prevState是老初始化的属性和状态,一般可以将dom元素的监听事件放在该函数中,通过判断
`if(!元素 || this._isbind) return ; this._isbind =true ;元素.addEventListener(‘scroll’, utils(this.scrollHandle, 200)); // 给图片列表绑监听事件
三、销毁阶段
1、componentWillUnmount()
组件被销毁时触发。这里我们可以进行一些清理操作,例如清理定时器,取消Redux的订阅事件等等。