目录
一 生命周期介绍
是什么?
组件从创建到挂载到页面上运行,再到组件不用时卸载的过程 叫生命周期
只有类组件才有生命周期
作用?
学习组件的生命周期,有助于理解组件的运行方式,完成更复杂的组件功能、分析组件错误原因等.
二 钩子函数介绍
是什么?
生命周期的每个阶段总是伴随着一些方法调用,这些方法就是生命周期的钩子函数
作用?
为开发人员在不同阶段操作组件提供了时机
三 生命周期的三个阶段
创建时、更新时、卸载时 常用钩子函数 图
3.1 创建时(挂载阶段)
1 执行时机: 组件创建时,页面加载时
2 钩子函数执行的顺序: constructor → render → componentDidMount
测试代码
import React from "react";
import ReactDOM from "react-dom";
class App extends React.Component {
//初始化state
constructor(props){
super(props)
console.warn("生命周期钩子函数:constructor")
}
//进行DOM操作
//发送ajax请求,获取远程的数据
componentDidMount(){
console.warn("生命周期钩子函数:componentDidMount")
}
//渲染UI
render() {
console.warn("生命周期钩子函数:render")
return(
<div>
<h1>123</h1>
</div>
)
}
}
ReactDOM.render(<App/>, document.getElementById("root"));
3 钩子函数的作用:
constructor → 初始化state,为事件处理程序绑定this
render → 渲染UI
componentDidMount → 发送网络请求,进行DOM操作
注意:
不要在render方法里再调用setState()
因为setState()可以调render更新UI
如果在render()里调了setState,就会导致render又被调用,就会导致递归,会导致报错
3.2 更新时
1 执行时机:(以下三种任意一种变化,组件就会重新渲染)
setState()
组件接收到新的props
forceUpdate()
2 钩子函数执行的顺序:
render → componentDidUpdate
3 钩子函数的作用
render → 渲染UI
componentDidUpdate → 发送网络请求,进行DOM操作
测试代码
import React from "react";
import ReactDOM from "react-dom";
class App extends React.Component {
state = {
num: 0
}
//初始化state
constructor(props) {
super(props)
console.warn("生命周期钩子函数:constructor")
}
//进行DOM操作
//发送ajax请求,获取远程的数据
componentDidMount() {
console.warn("生命周期钩子函数:componentDidMount")
}
componentDidUpdate() {
console.warn("生命周期钩子函数:componentDidUpdate")
}
//更新页面
handleClick = () => {
this.setState({
num: this.state.num + 1
}
)
}
//渲染UI
render() {
console.warn("生命周期钩子函数:render")
return (
<div>
<div>数量:{this.state.num}</div>
{/*点击按钮更新页面*/}
<button onClick={this.handleClick}>点我</button>
</div>
)
}
}
ReactDOM.render(<App/>, document.getElementById("root"));
效果:
每次点击按钮,更新页面的数量时,就会走render 和 componentDidUpdate
注意:
不要在 componentDidUpdate 里写setState()否则会递归更新
setState()会导致render()更新,render()会导致componentDidUpdate()
错误示范
如果要写setState()需要放在条件语句里
上一次的props: prevProps
componentDidUpdate(prevProps) {
console.warn("生命周期钩子函数:componentDidUpdate")
if(prevProps.num!==this.props.num){
this.setState({
num: this.state.num + 1
}
)
}
}
3.3 卸载时
1 执行时机:组件从页面中消失
2 钩子函数执行的顺序:
只有这一个钩子函数执行:componentWillUnmount
3 钩子函数的作用: 执行清理工作
测试代码
import React from "react";
import ReactDOM from "react-dom";
class App extends React.Component {
state = {
num: 0
}
handleClick = () => {
this.setState({
num: this.state.num + 1
}
)
}
render() {
return (
<div>
{
// num>3时, Counter组件就消失了
this.state.num > 3 ? (<div>豆豆被打死了</div>) :
(<Counter num={this.state.num}></Counter>)
}
{/*点击按钮更新页面*/}
<button onClick={this.handleClick}>打豆豆</button>
</div>
)
}
}
class Counter extends React.Component {
//组件消失时执行
componentWillUnmount() {
console.warn("生命周期钩子函数:componentWillUnmount")
}
render() {
return (
<div>打了{this.props.num}次</div>
)
}
}
ReactDOM.render(<App/>, document.getElementById("root"));
num > 3时
num > 3时, Counter组件消失了 , componentWillUnmount 执行了
定时器清理示范
设置了一个定时器, 原来是 豆豆被打死了,定时器还在执行,但是豆豆被打死了后, 定时器执行毫无意义
在componentWillUnmount 里设置定时器清理
代码
import React from "react";
import ReactDOM from "react-dom";
class App extends React.Component {
state = {
num: 0
}
handleClick = () => {
this.setState({
num: this.state.num + 1
}
)
}
render() {
return (
<div>
{
// num>3时, Counter组件就消失了
this.state.num > 3 ? (<div>豆豆被打死了</div>) :
(<Counter num={this.state.num}></Counter>)
}
{/*点击按钮更新页面*/}
<button onClick={this.handleClick}>打豆豆</button>
</div>
)
}
}
class Counter extends React.Component {
componentDidMount() {
this.timerId=setInterval(
() => {
console.log("定时器正在执行")
}, 500
)
}
//组件消失时执行
componentWillUnmount() {
console.warn("生命周期钩子函数:componentWillUnmount")
//清理定时器
clearInterval(this.timerId)
}
render() {
return (
<div>打了{this.props.num}次</div>
)
}
}
ReactDOM.render(<App/>, document.getElementById("root"));
豆豆被打死后, 定时器被清理了,不再执行
四 不常用的钩子函数