一. React的生命周期
这里render渲染函数会执行两次,第一次是当组件初始化完成的时候,第二次是当组件完成从数据的修改的时候再执行一次
1.创建和初始化到的生命周期:
(1) getDefaultProps(15.6版本的):初始化props值
(2)componentWillReceiveProps(废弃): 这是监听props值变化的生命周期
(3) getInitialState(15.6版本):初始化state值
2. 挂载阶段:
(1)componentWillMount: 挂载之前,在这里执行的东西是在render(让虚拟DOM转换为真实DOM)函数的前面,这个生命周期在17版本之后就会被废弃,现在它是一个不安全的生命周期
(a)可以获取this以及state里面的数据,不可以获取DOM元素
在这个生命周期里面修改数据可以直接引起页面的改变,这是因为这个生命周期的执行是在render渲染函数之前执行的,如果在这个生命周期里面修改数据,也就是修改数据的时候render还没有渲染页面,当执行完这个生命周期之后就去执行render函数,这个时候就会根据这个生命周期修改以后的数据离开渲染页面
(b)但是不会触发其他运行中的生命周期
(c)这个生命周期不常用,不可以在这里进行数据的网络请求,否则的话有可能会导致数据网络的请求重复执行
(d)16.3版本之后的react是异步渲染(fiber),渲染前的这个生命周期可能会被意外情况打断,那么生命周期就会重新执行 ,所以如果在这个生命周期里面执行网络请求里面,可能会造成发起多次的网络请求
(2) componentDidMount: 挂载之后,在这个生命周期中有可以获取到DOM元素、数据,一般咋这里生命周期中做数据的网络请求,以及初始化swiper、better-scroll。
(a)数据的修改不能直接引起页面的改变,需要通过setState设置才可以
(b)数据点修改会触发运行中的生命周期
3. 更新阶段 :
(1) componentWillReceiveProps: 将要接收改变之后的props值,props里面的数据发生改变的时候触发;
(2) shouldComponentUpdate: 在这里判断,数据的改变是否引起页面的改变,当没有在代码中写这个函数的时候,默认返回的是true,数据改变,页面就会发生改变,所以可以通过在这个生命周期里面判断数据是否发生改变来决定是否需要重新更新页面,来减少DOM操作
(a)当在生命周期函数里面return false;// 当返回false的时候,表示数据发生改变也不改变页面,就不会再去执行render函数,渲染页面
(b)当在生命周期函数里面return true;// 当返回true的时候,表明当数据发生改变的时候,页面也需要发生改变,这个时候会每改变一次就执行一次render函数渲染界面
(c)shouldComponentUpdate(props,state): 会接收到两个参数,第一个参数是props里面数据改变的值,第二个参数是state里面数据发生改变的值
(3)componentWillUpdate: 这里是组件更新之前。里面的DOM元素以及数据都是更新之前的,这个生命周期也是放在render函数的前面,这个生命周期也即将被废弃。
在这个生命周期中需要减少对数据进行更改的操作,否则会造成死循环,因为数据已更新就会触发这个生命周期函数
(4) componentDidUpdate: 组件已经个更新完毕,在这个生命周期中需要减少对数据进行更改的操作,否则会造成死循环,因为数据已更新就会触发这个生命周期函数
4.卸载阶段: componentWillUnMount:当组件销毁的时候执行该生命周期函数
举个小例子
```
根组件文件
import React,{ Fragment } from 'react'
在这里引入生命周期例子的组件
import Mount from './life/Mount'
function App () {// 函数创建组件
return (
<Fragment>
这里是根组件
使用组件
<Mount></Mount>
</Fragment>
)
}
export default App
```
```
子组件文件
import React,{ Component } from 'react'
class Mount extend Component {
super()// 执行构造函数
constructor() { // 构造函数
console.log('初始化',this)// 这里拿到的this就是Mount组件本身
this.state = {
name: '韩梅梅'
}
}
这里是组件挂载之前的生命周期
componentWillMount() {
console.log(this)// 可以拿到组件本身
cosnole.log(this.state.name) // 在这个生命周期里面可以获取到state里面的数据
console.log(this.refs.p) // undefined 这组件挂载之前的生命周期中,不能获取到DOM元素,因为这个时候虚拟DOM数据还没有挂载到真实DOM元素上
this.state.name = '李雷雷'// 这个生命周期中可以修改state里面的数据而且会使页面发生改变,并且不会触发进行中的生命周期
}
这个是组件挂载之后的生命周期
componentDidMount() {
console.log(this)// 可以拿到组件本身
cosnole.log(this.state.name) // 这个生命周期里面可以拿到state里面的数据
console.log(this.refs.p) // 这个生命周期里面可以拿到DOM元素
this.state.name = '李雷雷'// 在这个生命周期中直接这样更改数据,页面是不会发生改变的,因为在这个生命周期的后面,还有其他的生命周期需要执行
this.setState({name:'李雷雷'}) //但是可以通过setState方法来更改数据
}
这里是运行中的生命周期(state值发生改变,或者是props值发生改变 触发shouldComponentUpDate生命周期),但是当这个生命周期存在这里的时候,数据发生改变之后并不一定会引起页面的改变
里面会接收两个参数,第一个参数是props里面数据改变的值,第二个参数是state里面数据发生改变的值
shouldComponentUpDate(props,state) { // 因为这个生命周期是一个疑问句的方式,需要在确定,当数据发生改变的时候,是否需要页面去发生改变
console.log('数据发生改变');
if (this.state.name = state.name) { // 判断state数据里面的值,与当前触发这个生命周期拿到的参数值是否一致,一致说明state值没有发生改变,不需要重新渲染界面
return false;// 当返回false的时候,表示数据发生改变也不改变页面,就不会再去执行render函数,渲染页面
} else {
return true;// 当返回true的时候,表明当数据发生改变的时候,页面也需要发生改变,这个时候会每改变一次就执行一次render函数渲染界面
}
}
render() { //render渲染函数
return (
<div>
<h1>挂载组件</h1>
<p ref = 'p'>{this.state.name}</p>
给一个按钮用来改变state里面的数据,当state值发生改变的时候就会触发shouldComponentUpDate的生命周期,如果写了这个生命周期,虽然数据会发生改变,但是页面不会发生改变
<button onClick = {
this.setState({name: '李雷雷'})
}>改值</button>
</div>
)
}
这里是更新之前的生命周期函数
componentWillUpdate () {
console.log('更新之前')
console.log(this)// 可以拿到组件本身
cosnole.log(this.state.name) // 这个生命周期里面可以拿到state里面的数据
console.log(this.refs.p) // 结果是<p>李雷雷</p> 这个生命周期里面可以拿到DOM元素,但是在这里拿到的DOM元素里面渲染的数据是不真实的,因为这里是更新之前,数据并没有做完更新
console.log(this.refs.p.innerText)//结果是韩梅梅 使用innerText拿到的才是DOM元素真是的文本内容
}
这里是更新结束之后的生命周期函数
componentDidUpdate () {
console.log('更新结束')
console.log(this)// 可以拿到组件本身
cosnole.log(this.state.name) // 这个生命周期里面可以拿到state里面的数据
console.log(this.refs.p) // 结果是<p>李雷雷</p> 这个生命周期里面可以拿到DOM元素,但是在这里拿到的DOM元素里面渲染的数据是不真实的,因为这里是更新之前,数据并没有做完更新
console.log(this.refs.p.innerText)//结果是韩梅梅 使用innerText拿到的才是DOM元素真是的文本内容
}
}
export default Mount
```