一、首先当组件第一次渲染的时候会执行哪些生命周期函数?
constructor--->componentWillMount--->render--->componentDidMount
![](https://img-blog.csdnimg.cn/2022010613262359020.png)
constructor:
初始化
当前生命周期函数可以用来定义当前组件所需要的一些状态
当前生命周期里面必须要写super如果不写会报错/或者this的指向可能发生改变
如果在super和constructor中没有传递props这个参数的话是访问不到this.props属性的,反之可以进行访问
componentWillMount:
组件挂载前:
在当前生命周期函数里面可以访问到props属性,在这里可以接受到外部属性,同时可以将外部属性转换为内部属性----(this.state.属性名 = this.props.自定义属性名)
在当前生命周期函数里面不需要调用setState,因为当前函数执行完毕以后就会执行render函数
render:
1、render函数什么时候会执行?
a、当this.props/this.state发生改变的时候render函数就会去执行。
2、this.props/this.state发生改变的时候会执行哪些生命周期函数
this.state:
shouldComponentUpdate--->componentWillUpdate--->render--->componentDidUpdate
this.props
componentWillReceiveProps--->shouldComponentUpdate--->componentWillUpdate--->render--->componentDidUpdate
2、render函数执行的时候会将虚拟DOM和数据进行相结合,在缓存中缓存一份虚拟DOM,当数据发生改变的时候
会将新的虚拟DOM与缓存中的虚拟DOM进行比较(diff算法)。比较完毕以后,将缓存的虚拟Dom中需要被更新的数据进行相应的批量修改。
而不是全部修改,减少不必要的更新
虚拟dom是真实的js对象
3、什么叫做diff算法
新旧两个虚拟DOM的对比就是tree diff
componentDidMount:
render函数执行完毕以后componentDidMount就会去执行。在这个生命周期函数里面我们可以进行fetch的请求
以及获取到真实的DOM结构
操作DOM的两种方式(在componentDidMount中进行操作,获取到的是真实的dom结构)
1、ref="组件名" this.refs.组件名
2、ref={(tagName)=>{this.key = tagName}} this.key
App.js
import React,{Component} from "react"
import List from './component/list'
class App extends Component{
constructor(){
super();
this.state={
message:'11111'
}
}
render(){
let {message} = this.state
return(
<div>
<List fa={message}></List> {/*父组件通过自定义属性给子组件传值*/}
</div>
)
}
}
export default App
list.js
import React,{Component} from 'react'
class list extends Component{
constructor(){
super();
this.state={
name:'张尚然',
age:22,
val:1000000
}
console.log("constructor--------")
console.log(this.props) //undifined
}
componentWillMount(){
console.log("componentWillMount--------")
console.log(this.props) //{} 因为父组件还没有给子组件传值,如果传值会有{fa:"11111"}
}
render(){
let {name,age,val} =this.state
let {fa} = this.props //接收父组件传过来的值
console.log("render--------")
return(
<div>
<div id="list">
<p>{name}</p>
<p>{age}</p>
<p>{val}</p>
<p>{fa}</p> {/*这是父组件传过来的值*/}
</div>
</div>
)
}
componentDidMount(){
console.log("componentDidMount--------")
}
}
export default list
ps: 操作DOM的两种方式
1、ref="组件名" this.refs.组件名
![](https://img-blog.csdnimg.cn/2022010613262317082.png)
list.js
render(){
let {val} =this.state
let {fa} = this.props
return(
<div>
<div id="info" ref='list'>
<p>{val}</p>
<p>{fa}</p> {/*这是父组件传过来的值*/}
</div>
</div>
)
}
componentDidMount(){
console.log(this.refs.list) //这里的this是组件
}
2、ref={(tagName)=>{this.key = tagName}} this.key
list.js
render(){
let {val} =this.state
let {fa} = this.props
return(
<div>
<div id="info" ref={(abc)=>{this.box=abc}}> //abc是形参代表当前的虚拟dom元素,也就是名为info的div,可以随便命名,this是当前组件list,这一步是将abc代表的虚拟dom元素赋值给了this.box,然后我们在下面可以通过this.box访问到这个虚拟dom中包含的所有标签
<p>{val}</p>
<p>{fa}</p> {/*这是父组件传过来的值*/}
</div>
</div>
)
}
componentDidMount(){
console.log(this.box) //这里的this是组件
}
二、组件销毁
componentWillUnmount( )
![](https://img-blog.csdnimg.cn/2022010613262398034.png)
list.js
(这里用到了子组件给父组件传值的知识点)
import React,{Component} from 'react'
class list extends Component{
constructor(){
super();
}
render(){
let {fa} = this.props
return(
<div>
<div id="info" ref={(abc)=>{this.info1=abc}}>
<p>{fa}</p>
<button onClick={this.handleClick.bind(this)}>销毁</button> //这里是子组件触发一个点击事件给父组件中子组件标签中的show自定义属性中传递一个值
</div>
</div>
)
}
handleClick(){
this.props.show(false);
//这是传递给父组件中show属性的值
}
componentWillUnmount(){ //这是组件被销毁时才会执行的生命周期钩子函数
console.log("componentWillUnmount------")
}
}
export default list
App.js
import React,{Component} from "react"
import List from './component/list'
class App extends Component{
constructor(){
super();
this.state={
flag:true
}
}
render(){
let {message,flag} = this.state
return(
<div>
{flag?<List fa={message} show={this.handleShow.bind(this)}></List>:''} //这是一个三目运算,flag为true的时候就显示dom元素,为false的时候就清空dom元素
</div>
)
}
handleShow(val){
this.setState({
//将子组件传过来的值清空
flag:val
})
}
}
export default App
三、外部属性值改变时会执行哪些钩子函数?
componentWillReceiveProps------>shouldComponentUpdate------->componentWillUpdate------->render------->componentDidUpdate
componentWillReceiveProps(newProps):
当外部属性发生改变的时候就会执行当前生命周期函数,当前生命周期函数会有一个参数是新的Prop
![](https://img-blog.csdnimg.cn/2022010613262416709.png)
外部的属性数据发生了改变就用这个钩子函数来接收新的数据来渲染到页面上
App.js
import React,{Component} from "react"
import List from './component/list'
class App extends Component{
constructor(){
super();
this.state={
message:'外部数据',
}
}
render(){
let {message} = this.state
return(
<div>
<List/>
<button onClick={this.handleOutData.bind(this)}>外部数据</button>
</div>
)
}
handleOutData(){
this.setState({
message:'修改过后的外部数据'
})
}
}
export default App
list.js
import React,{Component} from 'react'
class list extends Component{
constructor(){
super();
this.state={
name:'旧值',
fa:''
}
}
componentWillMount(){
this.state.fa = this.props.fa //this.state中的fa 被赋值为 页面第一次渲染时从外部传来的值
}
render(){
let {fa} =this.state
console.log("render--------")
return(
<div id="info" ref={(abc)=>{this.info1=abc}}>
<p>{fa}</p>
</div>
)
}
componentWillReceiveProps(newProps){
console.log("componentWillReceiveProps------")
console.log(newProps)
//修改过后的外部数据
this.state.fa = newProps.fa
//这是让this.state中的fa 被赋值为 外部传来的newProps中的fa值
}
shouldComponentUpdate(newProps,newState){ //第一个参数是父组件传过来的新值,第二个参数是子组件中被改变后的新值
console.log("shouldComponentUpdate--------")
console.log(this.state.name,1) //旧值
console.log(newProps) //修改过后的外部数据
console.log(newState) //旧值,因为没有往this.state中传值
}
componentWillUpdate(newProps,newState){
console.log("componentWillUpdate----------")
console.log(this.state.name,2) //旧值
console.log(newProps) //修改过后的外部数据
console.log(newState) //旧值
}
componentDidUpdate(oldProps,oldState){
console.log("componentDidUpdate------------")
console.log(this.state.name,3) //新值
console.log(oldProps) //修改过后的外部数据
console.log(oldState) //旧值
}
}
export default list
四、当内部属性值 (this.state)发生改变时 执行哪些钩子函数?
shouldComponentUpdate------>componentWillUpdate------->render---------->componentDidUpdate
shouldComponentUpdate(newProps,newState):
1、当this.state/this.props发生改变的时候会执行render函数,
2、shouldComponentUpdate这个生命周期函数必须要返回一个布尔值 如果返回true则下面的生命周期函数继续执行,
如果返回false下面的生命周期函数不在执行,render不会重新渲染被更改的dom元素
3、shouldComponentUpdate这个生命周期函数主要是用来判断DOM是否更新 而不是数据是否更新(不管返回值是true或者
false,this.state中的数据肯定会发生改变,但是如果返回值是false的情况下DOM是不会进行更新的,页面不会发生变化 )
4、shouldComponentUpdate这个生命周期函数里面我们可以做一些相关的操作来减少虚拟DOM不必要的更新(利用
shouldComponentUpdate中接受到的2个参数 一个是新的props 一个是新的state 进行比较 )
componentWillUpdate(newProps,newState)
:
更新前:
虚拟DOM与数据进行相结合,但是没有生成真正的DOM结构 this.state中的数据还是旧的
render()
componentDidUpdate(oldProps,oldState):
更新后:
数据和模板进行相结合生产了真正的DOM结构,在这里可以获取到数据更新后最新的DOM结构
![](https://img-blog.csdnimg.cn/2022010613262474623.png)
list.js
import React,{Component} from 'react'
class list extends Component{
constructor(){
super();
this.state={
name:'旧值',
fa:''
}
console.log("constructor--------")
console.log(this.props) //undifined
}
componentWillMount(){
console.log("componentWillMount--------")
console.log(this.props) //{} 因为父组件还没有给子组件传值,如果传值会有{fa:"11111"}
this.state.fa = this.props.fa
}
render(){
let {name,age,val,fa} =this.state
console.log("render--------")
return(
<div>
<div id="info" ref={(abc)=>{this.info1=abc}}>
<p>{val}</p>
<p>{fa}</p>
<button onClick={this.handleUpdate.bind(this)}>修改数据</button>
</div>
</div>
)
}
handleUpdate(){
//通过点击事件来触发这个方法,执行this.setState 改变this.state中的值 当触发了这个方法的时候钩子函数的执行顺序是 shouldComponentUpdate---->componentWillUpdate----->render----->componentDidUpdate
this.setState({
name:'新值'
})
/*setTimeout(()=>{
//用定时器来证明当shouldComponentUpdate的值为false的时候render等函数不执行但是数据是发生了改变的
console.log(this.state.name) //新值
},3000)*/
}
componentDidMount(){
console.log("componentDidMount--------")
console.log(this.info1) //这里的this是组件
}
componentWillUnmount(){ //组件销毁
console.log("componentWillUnmount------")
}
shouldComponentUpdate(newProps,newState)
{
//第一个参数是父组件传过来的新值,第二个参数是子组件中被改变后的新值
console.log("shouldComponentUpdate--------")
console.log(this.state.name,1) //旧值
console.log(newProps) //fa:{11111}
console.log(newState) //新值
if(newState.name!=this.state.name){
//这里的newState中的值就是setState中传过来的被修改的值 如果setState中新改变的name值不等于原本的this.state中的值那么就return true,执行了这个操作之后this.state中的name就变为了“新值”,与newState获取到的值相等,所以return false
return true
}else{
return false
}
}
componentWillUpdate(newProps,newState){
console.log("componentWillUpdate----------")
console.log(this.state.name,2) //旧值
console.log(newProps) //fa:{11111}
console.log(newState) //新值
}
componentDidUpdate(oldProps,oldState)
{
console.log("componentDidUpdate------------")
console.log(this.state.name,3) //新值
console.log(oldProps) //fa:{11111}
console.log(oldState) //旧值
}
}
export default list
react生命周期函数中有哪些生命周期函数只会执行一次?
constructor
componentWillMount
componentDidMount
componentWillUnMount
react生命周期函数中有哪些生命周期函数会执行多次?
componentWillRecevieProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate