一、组件生命周期
概述
-
意义:组件的生命周期有助于理解组件的运行方式,完成更复杂的组件功能、分析组件错误原因等
-
组件的生命周期: 组件从被创建到挂载到页面中运行,再到组件不在时卸载的过程
-
生命周期的每个阶段总是伴随着一些方法调用,这些方法就是生命周期的
钩子函数
-
构造函数的作用:为开发人员在不同阶段操作组件提供了时机
-
只有类组件才有生命周期
二、生命周期阶段
2.1 创建时(挂载阶段)
- 执行时机:组件创建时(页面加载时)
- 执行顺序
钩子函数 | 触发时机 | 作用 |
---|---|---|
constructor | 创建组件,最先执行 | 1、初始化state 2、为事件处理程序绑定this |
render | 每次组件渲染都会触发 | 渲染UI(注意:不能调用setState() ) |
componentDidMount | 组件挂载(完成dom渲染之后) | 1、发送网络请求 2、DOM操作 |
- this.setState在render函数中错误使用的报告
- 实例
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
constructor(props) {
console.warn('这是constructor钩子函数')
// const title = document.getElementById('title')
// console.log(title) null
super(props)
// 初始化数据
this.state = {
value: 100
}
}
render() {
console.warn('这是render钩子函数')
// const title = document.getElementById('title')
// console.log(title) null
// 不能在render函数中使用this.setState,会报错
// this.setState({
// value: 200
// })
return <div id="title">Hello World</div>
}
componentDidMount() {
console.warn('这是componentDidMount钩子函数')
const title = document.getElementById('title')
console.log(title)
// <div id="title">Hello World</div>
}
}
ReactDOM.render(<App />, document.getElementById('root'))
2.2 更新时
执行时机:
- 1、
setState()
- 2、组件接收到新的
props
- 3、
forceUpdate()
(强制更新函数)
说明:以上三者任意一种变化,组件就会重新渲染
钩子函数 | 触发时机 | 作用 |
---|---|---|
render | 每次组件渲染时都会触发 | 渲染UI(与挂载阶段作用相同) |
componentDidUpdate | 组件更新(完成DOM渲染)后 | 1、发送网络请求 2、DOM操作 注意:如果要setState()必须放在一个if条件中 |
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
constructor(props) {
super(props)
// 初始化数据
this.state = {
count: 100
}
}
clickHandle = () => {
this.setState({
count: this.state.count + 1
})
// this.forceUpdate()
}
render() {
console.warn('render函数')
return (
<div>
<Counter count={this.state.count} />
<button onClick={this.clickHandle}>计数器</button>
</div>
)
}
}
class Counter extends React.Component {
render() {
console.warn('子组件render函数')
return <h1>当前数字为:{this.props.count}</h1>
}
componentDidUpdate(pre) {
console.warn('componentDidUpdate钩子函数')
// 注意不能使用setState函数,会导致更新的递归调用渲染
// this.setState({})
// 正确用法,用if判断
console.log('上一次的props:', pre, ',这一次的props:', this.props)
if (pre.count !== this.props.count) {
this.setState({})
// 或者发送ajax请求
}
}
}
ReactDOM.render(<App />, document.getElementById('root'))
2.3 卸载时
-
执行时机:组件从页面中消失
-
作用:用来做清理操作
钩子函数 | 触发时机 | 作用 |
---|---|---|
componentWillUnmount | 组件卸载时(从页面消失) | 执行清理工作(比如:清理定时器等) |
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
constructor(props) {
super(props)
// 初始化数据
this.state = {
count: 100
}
}
clickHandle = () => {
this.setState({
count: this.state.count + 1
})
}
render() {
console.warn('render函数')
return (
<div>
{this.state.count > 103 ? (
<span>计数停止</span>
) : (
<Counter count={this.state.count} />
)}
<button onClick={this.clickHandle}>计数器</button>
</div>
)
}
}
class Counter extends React.Component {
componentDidMount() {
// 开启定时器
this.timerID = setInterval(() => {
console.log('定时器运行中')
}, 500)
}
render() {
console.warn('子组件render函数')
return <h1>当前数字为:{this.props.count}</h1>
}
componentWillUnmount() {
console.warn('componentWillUnmount钩子函数被执行')
// 清除定时器
clearInterval(this.timerID)
}
}
ReactDOM.render(<App />, document.getElementById('root'))