概念
组件从被创建到挂载到页面中运行,再到组件不用时卸载的过程。
只有类组件才有生命周期。
分为三个阶段:
- 挂载阶段
- 更新阶段
- 销毁阶段
三个阶段
挂载阶段
钩子函数 - constructor
创建阶段触发
作用:创建数据
- 之前定义状态是简写,完整写法是写在constructor函数中
- 包括props之前也是简写,完整写法是写在constructor函数中
- 包括ref【获取真实DOM元素/获取类组件实例】的创建,也要写在constructor函数中
class Son extends Component {
constructor(props) {
// 【创建阶段,目的是创建数据】最先执行
super()
this.state = {
b: props.a,
}
this.iptRef = createRef()
}
// iptRef = createRef() // 建立ref的简写
}
钩子函数 - render
渲染阶段触发 (每次组建渲染都会触发)
作用:渲染UI
render() {
return (
<>
hi :{this.state.b}
<input type="text" ref={this.iptRef} />
</>
)
// return <>hi :{this.props.a}</> // props的简写
}
钩子函数 - componentDidMount
完成DOM渲染后触发
作用:发送请求;DOM操作
componentDidMount() {
// 【组建挂载完毕,目的是:发送请求;DOM操作】完成DOM渲染后触发
console.log('componentDidMount')
}
执行顺序
class App extends Component {
// 挂载阶段,会经过三个钩子:constructor render componentDidMount
constructor() {
// 【创建阶段,目的是创建数据】最先执行
super()
console.log('constructor')
}
render() {
// 【渲染阶段,目的是渲染UI】每次组建渲染都会触发,(注意⚠️ :不能调用setState()原因是render是每次组件渲染时触发的,如果在里面凋setState(),则组件数据发生变化,肯定要重新渲染,但是重新渲染又会触发render。就会形成死循环!!!)
console.log('render')
return (
<>
</>
)
}
componentDidMount() {
// 【组建挂载完毕,目的是:发送请求;DOM操作】完成DOM渲染后触发
console.log('componentDidMount')
}
}
更新阶段
更新含义:数据发生变化就会引起组件的更新
钩子函数 - render()
每次组件重新渲染(数据发生变化)执行
- 默认挂载阶段会执行一次
- 更新阶段执行
- 调用了setState方法
- forceUpdate(强制更新)
- props传递的数据更新了
钩子函数 - componentDidUpdate()
- 更新阶段执行
- 调用了setState方法
- forceUpdate(强制更新)
- props传递的数据更新了
import React, { Component } from 'react'
import ReactDOM from 'react-dom/client'
export default class App extends Component {
// 挂载阶段,会经过三个钩子:constructor render componentDidMount
constructor() {
// 【创建阶段,目的是创建数据】最先执行
super()
this.state = {
a: 100,
b: 50,
}
console.log('constructor')
}
handelChange = () => {
this.setState({
a: this.state.a + 1,
})
this.state.b += 1
this.forceUpdate() // 强更新(强制DOM更新) 如果不调用这个方法,b的数据会变化,但是,DOM无法更新
console.log(this.state.b)
}
render() {
console.log('render')
return (
<>
<div>
{this.state.a} --- {this.state.b}
</div>
<button onClick={this.handelChange}>修改</button>
</>
)
}
componentDidMount() {
// 【组件挂载完毕,目的是:发送请求;DOM操作】完成DOM渲染后触发
console.log('componentDidMount')
}
componentDidUpdate() {
// 【组件更新完毕】
console.log('componentDidUpdate')
}
}
ReactDOM.createRoot(document.querySelector('#root')).render(<App></App>)
卸载阶段
钩子函数 - componentWillUnmount()
import React, { Component } from 'react'
let timer = -1
export default class Son extends Component {
constructor() {
super()
console.log(' Son子组件的constructor')
timer = setInterval(() => {
console.log('定时器执行')
}, 1000)
}
render() {
console.log('Son子组件的render')
return <div>Son</div>
}
componentDidMount() {
console.log('Son子组件的componentDidMount')
}
componentDidUpdate() {
console.log('Son子组件的componentDidUpdate')
}
// 【组件卸载,执行一些清理工作】组件即将销毁的时候,要将全局的定时任务,全局变量,全局...等等销毁
componentWillUnmount() {
clearInterval(timer)
console.log('Son子组件销毁了componentWillUnmount')
}
}
父子组件的钩子函数执行顺序
父组件constructor → 父组件的render → 子组件的constructor → 子组件的render → 子组件的componentDidMount → 父组件的componentDidMount