为了进一步了解React的工做过程,已经晓得了怎么编写React组件,知道了React的数据流,那么是时候学习React组件的生命周期了,每一个组件都包含生命周期方法,生命周期如同四季更替,一我的的生,老,病,死.在每一个特殊的年龄阶段,作着不一样的事情javascript
在React编写组件中,一样,每一个组件在网页中都有被建立,更新,删除这么一过程,就像有机的生命体同样java
理解生命周期函数对于编写React组件代码是很是重要的react
若是你不清楚生命周期,以及生命周期的应用场景,那么本篇就是你想要知道的浏览器
生命周期(钩子)函数
定义: 在特定的阶段,可以自动执行的函数(方法)服务器
在前面的JSX学习中,一个React元素渲染到页面当中,本质上是经过底层的React.CreateElement的一个方法实现的,它是一个javascript对象,将虚拟DOM转化为真实的DOM,最后经过ReactDOM.render()方法将真实的DOM渲染挂载到对应的页面位置上网络
一个组件的渲染,经历了如下几个过程:能够对照这个生命周期图谱的 dom
三种不一样的过程,React库会依次调用组件的一些成员函数(生命周期函数)异步
装载过程
当组件第一次被渲染的时候,会依次的调用以下生命周期函数函数
使用场景:当组件内部的state变化依赖于props时,调用该生命周期函数 注意:不要过分使用该函数,若是你的操做依赖于props的更改并有反作用,最好放到componentDidUpdate中
它也只会在初始化的时候调用一次,因此this坏境的绑定放在这里面也是能够的,可是最好是放在constructor构造器函数里面,若是是处理带有后续异步操做或者有反作用的订阅事件处理,例如:Ajax数据获取,则放到componentDidMount中
constructor:构造器函数
constructor(ptops) {
super(props); // 必定要调用super,而且接收props参数,不然该组件的实例方法没法获取到外部的props值
}
复制代码
至于constructor在上节当中已经说起过,并非每一个组件都须要定义constructor构造器函数,函数式(无状态)组件就不须要定义构造函数
通常使用constructor构造函数有以下两种状况
为了方便调用,在构造函数中,this就是当前组件的实例,每每在构造函数中将组件实例下的成员方法绑定this为当前的实例对象
constructor(props){
super(props);
}
// 事件监听处理函数,this坏境的绑定
this.handleBtnClick = this.handleBtnCLick.bind(this);
this.handleInputChange = this.handleInputChange.bind(this)
复制代码
在执行了constructor构造器函数后,执行componentWillMount方法,而后在执行render方法,执行完render方法后,在执行componentDidMount方法,整个装载过程就结束了的
固然这其中的一个componentWillUnmount方法是在组件销毁前进行触发,也就是删除DOM元素以前调用,这个经常使用于当组件从页面删除销毁时,作一些数据清理的时候能用得上,例如定时器的清理,取消网络请求,在该生命周期函数内,不该该调用setState函数,由于该组件销毁后,将不会被从新渲染
具体的实例代码以下所示:
import React, { Fragment, Component } from 'react';
import ReactDOM from 'react-dom';
class LifeCycle extends Component {
constructor(props){
super(props);
console.log("1-constructor函数被调用执行");
this.state = {
isShow: true
}
this.handleBtnClick = this.handleBtnClick.bind(this);
}
componentWillMount(){
console.log("2-componentWillMount函数已执行,组件挂载以前,在render方法以前调用", this.state.isShow);
}
componentDidMount() {
console.log("4-componentDidMount函数已执行,组件挂载完以后,DOM元素已经插入到页面后调用");
}
render(){
console.log("3-render函数执行");
return (
<Fragment>
<div>
{ this.state.isShow? <Text />:""}
<button onClick={ this.handleBtnClick }>更改</button>
</div>
</Fragment>
);
}
handleBtnClick(){
this.setState({
isShow:!this.state.isShow
})
}
}
class Text extends Component {
componentWillUnmount(){
console.log("componentWillUnmount函数已执行,组件从页面中移除以前调用,Text组件移除");
}
render(){
console.log("Text组件被渲染");
return (
<h1>itclanCoder</h1>
);
}
}
const container = document.getElementById('root');
ReactDOM.render(<LifeCycle />, container);
复制代码
效果以下所示:
你们能够自行将这些生命周期函数放到组件内部当中,进行测试的,看每一个生命周期执行的顺序就一目了然了的
说完了组件的装载,那么接下来就是组件的更新了
组件的更新
当props或者state发生改变的时候,就会引发render函数的渲染,也就是会引起组件的更新,它与组件的装载同样,会触发一些生命周期函数
更新组件时:生命周期函数执行的顺序
你能够理解为,第一次渲染时,父组件的componentWillReceiveProps函数不会被执行,若是是第二次渲染时,已经存在于父组件中,则该componentWillReceiveProps才会执行
注意:在挂载过程当中,React不会针对初始props调用此方法,经过触发setState方法更新过程不会调用这个函数,这是由于这个函数适合根据新的props值(也就是nextProps)来计算出是否是要更新内部状态state
应用场景:当你但愿只有在接收新的props时作一些逻辑时,props改变须要相应改变内部state状态时,则使用componentWillReceiveProps,好比:根据父组件传入的数据初始化或重置组件内部的某些state状态
返回一个boolean值,告诉React库这个组件在此次更新过程是否要继续,若是该函数返回true,那么继续更新,调用render函数,反之,若函数返回false,那么马上中止更新过程,便不会执行render函数了的
这个函数是提升React的性能的,若是发现不必的渲染,那就干脆不用渲染了的,这个shouldComponentUpdate就能够作到
注意: forceUpdate不会触发该函数,也可使用PureComponent替代该函数,该函数作了内部的优化
// nextProps表示的是接下来个人props值会样,nextState表示的是个人state会变成什么样
shouldComponentUpdate(nextProps, nextState)
if(nextProps.props属性 !== this.props.props属性 || nextState.state属性 !== this.state.state属性)
return true;
}else{
return false
}
复制代码
注意: 不要在该函数中经过this.setState再次改变state,若是须要,则在componentWillReceiveProps函数中改变
注意:不能在render函数中调用setState,若是在shouldComponentUpdate返回false,则render函数不会被调用
应用场景:若是但愿不管props更改仍是组件内的状态更改都能触发一些逻辑,则可使用componentDidUpdate,进行业务处理,发送网络请求
注意:在处理业务或发送网络请求时,必定要作好条件比较,不然容易形成死循环
组件的卸载
React组件从页面中移除时,在卸载的过程当中,只涉及一个生命周期函数componentWillUnmount,因为该函数在组件删除以前会被调用,因此该函数适合作一些清理性的工做
应用场景: 清理无效的timer,取消未完成的网络请求,清理已注册的订阅
注意:在这里使用setState时无效的
固然对于React的生命周期,不一样的版本,官方对它作了一些优化和改动,这里介绍的是React Version 16.2.0版本的,生命周期过程图以下所示
若是是最新的,在React17.0版本中,生命周期函数以下所示
本文主要讲解了React的生命周期,只要理解了生命周期的图谱,生命周期也就差很少了的,在constructor构造器中初始化工做,componentWillMount在组件即将挂载以前执行调用,经常使用于组件的启动工做,例如:Ajax数据的获取,定时器的启动
固然数据的请求最好放在componentDidMount函数中,而当props或者state发生改变时,会引发组件的渲染,也就是组件的更新,只要父组件的render函数被渲染了,就会触发子组件的componentWillReceiveProps,而当shouldComponentUpdate的函数返回true时,则render函数会渲染,要是返回false时,则render函数不会渲染
当组件从页面中移除时,在卸载以前会触发componentWillUnmount函数,该函数经常用于组件销毁时调用,清理无效的定时器timer,取消未完成的网络(Ajax)请求,清理已注册的订阅