生命周期函数指在某一个时刻组件会自动调用执行的函数。
对一个React组件来说,它会经历一些过程,看下图。
- Initialization 组件的初始化过程,组件会初始化自己的一些数据,比如props,比如state,那么组件在哪里做的初始化呢? 是在constructor函数就是我们初始化的位置,我们在这里定义state,接收props。
- 初始化之后,组件要被渲染然后挂载到页面上,这个过程就是Mounting,组件被挂载到页面的过程会经历3个周期。注意:componentWillMount和componentDidMount只有在组件第一次挂载的时候,会被执行,后边数据变化的时候,只执行render生命周期。
// 在组件即将被挂载到页面的时刻自动执行,还没有被挂载。
componentWillMount(){
console.log('componentWillMount');
}
// render函数做页面的挂载
render(){
console.log('render');
return (
<Fragment>
<div>
{/*这是一种注释方式,下边是一个input框*/}
{
// 这是一个单行注释,之所以花括号要单独一行,就是避免被当成注释内容
}
<label htmlFor="inserArea">输入内容</label>
<input
id="inserArea"
className="input"
value={this.state.inputValue}
onChange={this.handleInputChange}
ref={(input) => {this.input = input}}
/>
<button onClick={this.handleBtnCick}>提交</button>
</div>
<ul ref={(ul) => {this.ul = ul}}>
{this.getTodoItem()}
</ul>
</Fragment>
)
}
// 组件被挂载到页面之后,自动被执行。
componentDidMount(){
console.log('componentDidMount')
}
- Updation组件更新流程。要么是props,要么是state发生变化,也就是数据发生变化的时候,页面的更新会被执行。props和state发生变化时,执行的生命周期函数有相同的,也有不同的。
相同的,shouldComponentUpdate(组件是否要被更新),这个函数需要返回布尔值,true就是需要更新,false就是不需要更新,后边的生命周期都不会执行了。componentWillUpdate、render、componentDidUpdate
不同的,componentWillReceiveProps
// 组件被更新之前,它会自动被执行。
shouldComponentUpdate(){
console.log('shouldComponentUpdate');
return true;
}
// 组件被更新之前,它会自动被执行,但是它在shouldComponentUpdate之后执行
// 如果shouldComponentUpdate返回true,componentWillUpdate才会执行
// 如果shouldComponentUpdate返回false,componentWillUpdate不会被执行
componentWillUpdate(){
console.log('componentWillUpdate');
}
// 组件更新完成以后,它会被执行
componentDidUpdate(){
console.log('componentDidUpdate');
}
// 当一个组件要从父组件接收参数
// 只要父组件的render函数被重新执行了,子组件的这个生命周期函数就会被执行
// 如果这个组件第一次存在于父组件中,不会执行
// 如果这个组件之前已经存在于父组件中,才会执行。
componentWillReceiveProps(){
console.log('child componentWillReceiveProps');
}
- Unmounting把组件从页面上去除的过程。
// 当这个组件,即将被从页面中剔除的时候,会被执行。
componentWillUnmount(){
console.log('child componentWillUnmount');
}
注意,react组件中,其他生命周期函数都可以不存在,唯有render必须要有,是因为创建组件的时候,继承了React.Component这个组件,这个组件默认内置了其他生命周期函数的默认实现,唯独没有内置render生命周期函数的默认实现。所以,render函数必须要自己实现。
React生命周期函数的使用场景
- 首先要知道,只有当一个组件的state或者props发生改变的时候,render函数才会重新执行;对一个组件来说,当这个组件的父组件的render函数重新执行的时候,父组件里的子组件的render函数,也会重新执行。这个逻辑上虽然是没错的,但是会带来性能上的损耗,因为如果子组件接收的props没变化(没必要重新渲染),只是父组件的数据发生了变化,从而导致子组件的render函数重新执行,的确是损耗了性能,那该怎么去做性能优化呢?这个时候就需要用到生命周期函数了。
// 子组件里设置这个钩子函数(返回false)。
// 意思就是,这个子组件被渲染一次之后,如果子组件需要更新,那么强制要求不更新。
shouldComponentUpdate(){
return false;
}
// 最优写法,加两个参数。
// nextProps 指的是,当组件要被更新的时候,组件的props要被更新成什么样
// nextState 指的是,当组件要被更新的时候,组件的state要被更新成什么样
shouldComponentUpdate(nextProps, nextState){
// 接下来props里的content如果不等于当前props里的content,
// 说明组件接收的props里的content的值发生了变化,需要让组件重新渲染。
// 否则就是content的值没有发生变化,就不需要组件重新渲染
if(nextProps.content !== this.props.content){
return true;
}else{
return false;
}
}
这样,我们就通过shouldComponentUpdate这个生命周期函数提升了组件的性能
。避免组件做无谓的render操作(render函数重新执行,就意味着react底层需要对组件生成一份虚拟DOM,与原来的虚拟DOM做比对,这个比对也是需要消耗一定的性能的)
。
一般情况下,我们把ajax请求,放在componentDidMount
生命周期里,因为在react里,componentDidMount函数,只会被执行一次。之所以不方在render生命周期函数里,是因为随着组件数据的变化,render函数会重复执行,那么ajax就会重复请求,肯定是不合适的。至于componentWillMount
其实也可以用来请求ajax,因为它也是只执行一次,但是当我们写ReactNative或者做服务器端的重构等更深技术的时候,可能会和一些更高端的技术产生冲突,为了避免这种可能存在的冲突,就干脆写到componentDidMount里。当然了,ajax也可以放在constructor里,但是不建议。
- 在react里发送ajax请求,可以借助axios,需要先安装。
网友评论