React生命周期大全:

react生命周期分三个阶段:

1、初始化阶段(挂载)

acomponentWillMount (): —— 用的较少,组件挂载到DOM前调用,且只会被调用一次,它代表的过程是组件已经经历了constructor()和state状态初始化数据后,但是还未渲染DOM
brender ():—— render函数会插入jsx生成的dom结构,react会生成一份虚拟DOM树,在每一次组件更新时,在此reacrt会通过其diff算法比较新旧的DOM树,比较后,重新渲染真实DOM。
ccomponentDidMount(): ——组件第一次渲染完成,此时DOM节点已经生成,可以在这里调用ajax请求,返回数据setState后组件会重新渲染。只更新一次

d、constructor

2、运行中阶段:(渲染)

acomponentWillUpdate(nextProps,nextState) ——DOM即将更新,shouldComponentUpdate为true之后 ,nextProps父组件的props更新的时候调用,nextState,自身组件的state状态
crender()——更新组件,生成虚拟DOM,做diff算法对比,渲染真实DOM。
bcomponentDidUpdate(prevProps,prevState)——DOM更新完成,每一次重新渲染都会进入,拿到两个参数,更新前的props和state

问题:当数据更新的时候,render()生命周期里面所有的组件都会更新,这样有的子组件不需要更新,会 消耗性能,可以用一下生命周期做判断。
dshouldComponentUpdate(nextProps,nextState)—— 主要用于性能优化(部分更新) Diff运算的开关, 唯一用于控制组件重新渲染的生命周期,由于在react中,setState以后,state发生变化,组件会进入重新渲染的流程,在这里return false可以阻止组件的更新。 因为react父组件的重新渲染会导致其所有子组件的重新渲染,这个时候其实我们是不需要所有子组件都跟着重新渲染的,因此需要在子组件的该生命周期中做判断、nextProps数据跟新之后的新数据,nextState:老的数据。里面必需写返回值

// if判断,组件应该更新吗? 应该true, 不应该返回false
// 性能优化生命周期
shouldComponentUpdate(nextProps,nextState){
console.log("shouldComponentUpdate")
console.log("老的状态",this.state)
console.log("新的状态",nextState)
if(JSON.stringify(this.state)===JSON.stringify(nextState)){
return false //如果新老状态一样,就不继续更新。false
}
return true //如果新老数据不一样,就说明需要更新,retrun
}

ecomponentWillReceiveProps(nextProps)—— 需要构建父子关系,在父组件传递给子组件的数据发送变化的时候,调用。
作用:根据属性,要请求后端数据的时候,根据属性筛选数据的时候,如果父组件数据传递给子组件要做逻辑计算操作的时候,就需要用这个组件,因为会多次调用。nextProps接收父组件修改后的props,需要重新渲染的时候使用。

以下代码实现需求:当点击每一个父组件中的内容的时候,子组件根据传递过来的ID,匹配对应的data数据渲染到页面

import React, { Component } from 'react'
class Child extends Component {
state={
data:[  //6、定义一个数组,
{MyId:1,name:"鞋子",price:98},
{MyId:2,name:"袜子",price:18},
],
gaiData:[] //7、定义一个空数组,用来存放对比Id后的数组,然后渲染到页面
}
render() {
return (
<div>{
this.state.gaiData.map((item) => //8、渲染除对比后的数组
<li key={item.price}>{item.name}</li>
)
}
</div>
)
}
// componentDidMount() {  //注:用这个生命周期不能做到,因为只会执行一次
// // console.log(this.props.id)
// this.setState({
// gaiData:this.state.data.filter((item) => item.MyId === this.props.id)
// })
// }
componentWillReceiveProps(nextProps) { //9、需要用到这个生命周期,当父组件传递过来的数据变化的时候,会多次调用
console.log("hhh",nextProps) //10、nextProps接收父组件改变后的属性
// this.state.list.filter()
this.setState({
gaiData:this.state.data.filter((item) => item.MyId ===nextProps.iud) //11、做过滤,过滤出子组件的Id跟父组件传递过来的id是否相等,相等就将那组数据给到gaiData数组,渲染出来
})
}
}
export default class App extends Component {
state={
list:[  //1、定义一个数组,在父组件中渲染出来
{id:1,name:"鞋子",price:18},
{id:2,name:"袜子",price:20},
{id:3,name:"裤子",price:28}
],
id:2 //2、定义一个id用来传递给子组件
}
render() {
return (
<div>
<ul>
{ //3、循环显示数组内容到页面
this.state.list.map((item) =>
<li key={item.id}>{item.name} 
<button onClick={() =>{ //5、给每一个li添加点击事件,将state定义的id 赋值为每一个li循环出来的id。
this.setState({
id:item.id
})
}}></button>
</li>
)
}
</ul>
<Child id={this.state.id}></Child> // 4、将state定义的id传递给子组件使用
</div>
)
}
}

3、销毁阶段;(卸载和数据销毁)

acomponentWillUnmount()——完成组件的卸载和数据销毁,如:清楚定时器,移出事件监听等。

二、新增的生命周期:

出现原因:因为componentWillMount() 和componentWillReceiveProps()
a、不安全,因为会做React-fiber调度机制存在,因为优先级的原因,会打断这几个生命周期,再次调用的时候,可能会出错。
b、老版本中的componentWillReceiveProps()方法判断前后两个 props 是否相同,如果不同再将新的 props 更新到相应的 state 上去。这样做一来会破坏 state 数据的单一数据源,导致组件状态变得不可预测,另一方面也会增加组件的重绘次数。
getDerivedStateFromProps这个新的生命周期,就是用来解决以上问题,替换componentWillMount和componentWillReceiveProps这两个生命周期的,
1getDerivedStateFromProps(nextProps,prevState): 必须要写static

static getDerivedStateFromProps(nextProps,nextState) {
console.log(nextState) //组件更新之前的状态,当前的state数据
console.log(nextProps) // 接收父组件更新后的Props数据
return {
text:"kerwin"+nextState.text //这里retrun可以直接修改state中的数据状态
}
}

2、getSnapshotBeforeUpdate(prevProps,pre。vState)
因为componentWillUpdate中更新数据需要通过很多程序,render创建jsx结构,生成虚拟DOM,对diff算法对比等操作,导致这个生命周期的记录数据这个功能效率变慢,会出现错误。所以出现了这个新的生命周期去替换willUpdate,精准的去记录状态数据,在每一次即将更新的那一刻,去记录当前状态。 并给到componentDidUpdate中进行相应处理。
getSnapshotBeforeUpdate会最终在render之前被调用,也就是在这个新的生命周期里读取到的DOM状态是和componentDidUpdate中的一致。
必需有retrun,并配合componentDidUpdate去使用

getSnapshotBeforeUpdate(){
console.log("getSnapshotBeforeUpdate")
return 100 //通过retrun出去更新前的状态
}

componentDidUpdate(prevProps, prevState,oldHeight) {
console.log("componentDidUpdate",oldHeight) //第三个参数拿到 上面记录的这个参数
//scrollTOP+= 新的scorllHeight- oldHeight
}

3、pureComponent 性能优化:

替换shouldComponentUpdate(nextProps,nextState)中做的性能优化对比,

1、第一步(引入)
import React, { Component, PureComponent } from 'react'
2、第二步:用它去包裹组件
export default class App extends PureComponent {//修改为他
render() {
return <div></div>
 }
}

猜你喜欢

转载自blog.csdn.net/weixin_46392334/article/details/107771508