和 Vue 或者小程序类似,React 也有生命周期函数;
react 生命周期官网参考文档:https://reactjs.org/docs/react-component.html#lifecycle-methods
下面通过例子来说明下面四个生命周期函数:
constructor() , componentWillMount() , componentDidMount() 和 render() ;
首先是 constructor ,我们可以在这个阶段进行数据的初始化操作,比如下面的代码,我们定义了一个数组cutme,
然后赋值给 state 的 abc ;
第二个是 componentWillMount() 函数,这个函数在执行完 constructor 之后执行; 在render() 之前执行;
也就是 constructor() ----> componentWillMount() ---------->render() 这个顺序;
第三个是 render() 函数,在执行 componentWillMount() 之后执行;这里就开始渲染页面了;
第四个是 componentDidMount () ,表示我们在render() 中渲染的页面已经挂载到页面中,可以正常的显示页面了;
代码如下:
export default class Func extends React.Component {
constructor(props){
console.log("功能页面 数据初始化");
super();
let cutme = [{name:'第一个数值'},{name:'第二个数值'},{name:'第三个数值'}]
this.state = {
abc: cutme
}
}
componentWillMount(){
console.log("功能页面 未渲染,刚初始化数据");
}
componentDidMount(){
console.log("功能页面 渲染完成");
}
render(){
console.log("功能页面 正在渲染");
return(
<div>
<p>我是功能页面</p>
<Datame id={this.state.abc} />
<Link to="/"><div>回到首页</div></Link>
</div>
)
}
}
上面简单描述了react 的一次正常进入的渲染过程,没有涉及到 update 等内容;
componentWillMount() 这个函数的使用按照官网所述可能会 产生一定的不稳定因素;所以这个函数的名字
也被修改成了 UNSAFE_componentWillMount() ,足以提醒开发者了,都加上不安全的标签了;
但是目前,这两种写法都是支持的;都可以使用;
上面了解了四个基础的函数,我们从简单开始,慢慢了解这些个生命周期函数的使用和含义;
下面看一下卸载页面的一个函数:componentWillUnmount()
代码就省略了,和上面的写法都是一样的,只是函数名不一样而已;
当我们离开一个页面的时候,会触发这个函数,也就是说,我们可以利用这个函数在我们离开页面之前做一些处理;
如果你在页面中使用定时器写了一个处理,当离开这个页面的时候,我们就可以利用这个函数停止这个定时器的进行;
释放浏览器的资源;
但是这个函数有一个很有意思的特征:
假设我们有一个功能页面 A ,首页页面是 B ;
我们在功能页面 A 中定义:
componentWillUnmount(){
console.log("功能页面 卸载之前");
}
那么我们从A离开 ,跳转B页面的时候会发生什么?
我们在生命周期的各个函数中console文字描述,如下:
首页Home的constructor
home.js:21 首页 Home 未渲染 componentWillMount
home.js:25 首页 Home 未渲染,UNSAFE_componentWillMount
home.js:37 首页 Home 正在渲染 render
func.js:25 功能页面 卸载之前 componentWillUnmount
home.js:29 首页 Home 渲染完成 componentDidMount
我们可以看到,页面跳转的过程中,先执行了要跳转到的首页页面B constructor()
然后执行了要跳转到的首页页面B componentWillMount() / UNSAFE_componentWillMount
再执行了要跳转到的首页页面B render()
这个时候才执行前一个页面A的 componentWillUnmount();
最后才执行心的页面的挂载操作;
所以通过上面的过程可以看到,前一个页面的卸载是在后一个页面要挂载之前才卸载,无缝对接,
后一个页面先渲染,然后再卸载前一个,挂载后一个;
下面看一下:componentWillUpdate 和 componentDidUpdate 这两个生命周期函数
这两个是在组件发生更新的时候才会触发的函数;
下面我们使用setState 引起重绘,触发上面这两个更新相关的生命周期函数;
我们随便创建一个组件,在组件的 constructor 中定义一个初始的状态 abc = 0 ;
然后再定义 componentWillUpdate () 和 componentDidUpdate(), 输出一点提示的文字;
最后再定义一个点击的函数 updateState ,在函数中使用 setState 改变之前的abc 的状态;
代码:
export default class Showme extends React.Component {
constructor(){
super();
this.state = {
abc: 0
}
this.updateState = this.updateState.bind(this);
}
componentWillUpdate(){
console.log("测试页面 componentWillUpdate");
}
componentDidUpdate(){
console.log("测试页面 componentDidUpdate");
}
updateState(){
this.setState({
abc: this.state.abc+1
})
}
render(){
return(
<p onClick={this.updateState}>{this.state.abc}我是测试的组件showme</p>
)
}
}
我们在点击这个段落 <p/> 的时候,就能在控制台看见输出:
测试页面 componentWillUpdate
测试页面 componentDidUpdate
我们使用 setState 函数引起组件重绘,触发了更新的两个函数;
也就是说,如果我们需要在数据改变后作相应的处理,可以通过这两个函数来做处理;
和之前的 componentWillMount 一样,这个 componentWillUpdate 函数也被视作可能导致不稳定因素出现的函数之一;
也修改了函数名,UNSAFE_componentWillUpdate ;
在上面测试 componentWillUpdate 和 componentDidUpdate 函数的时候,我们使用了 setState 来引起页面的重绘,
触发了这两个函数;我们在 constructor 中初始化的 abc = 0 ; 假设上面的点击的函数里面不改变这个abc 的值,
也就是还是设置这个 abc = 0; 虽然前后的的值是没有变化的,但是由于调用了 setState ,会导致页面的重绘,
也就是说,即使abc的值没有发生变化,还是触发了 componentWillUpdate 函数和 componentDidUpdate 函数,
但是这是没有必要的,浪费了资源;
react 的 shouldComponentUpdate 函数就可以解决上面的问题
shouldComponentUpdate 函数也是生命周期函数之一;
和前面的生命周期函数一样,写法如下:
shouldComponentUpdate(nextProps,nextState){
if(nextState.Number == this.state.Number){
return false;
}
}
这个函数的两个参数是 abc 的改变前的值和改变后的值;
在函数中利用条件判断进行处理,如果相同,也就是说 abc = 0; 使用 setState abc= 0 ;
前后的值没有变化,返回false , 这样就不会触发 componentWillUpdate 和 componentDidUpdate;
还有一个函数:componentWillReceiveProps
假设父组件在 constructor 中初始化了一个 abc = 0;
并且这个abc 还传给了 子组件;
那么子组件可以通过 props 获取这个abc 的值;
当父组件中的这个 abc = 0 改变为 abc = 1时;
就会在子组件中触发这个 componentWillReceiveProps((newProps) 函数,并且我们可以通过这个函数的参数获取改变的 abc = 1
这样我们就能够在子组件中修改 原本 abc =0 的值为 1;
子组件中如下使用方式:
componentWillReceiveProps(newProps) {
console.log("触发了props 函数");
this.setState({
def: newProps.para
});
}
上面就是常用的react 生命周期函数;