本章将讨论 React 组件的常用生命周期。
生命周期是指描述一个组件从挂载到销毁的“一生”的过程。React 组件完整的生命周期非常多,你可以在这里查看图示。本章将对常用的生命周期方法进行说明。
要明确一点:生命周期方法是由 React 自动调用的,而不是由程序员来手动调用。
常用生命周期
我希望你已经点开了上面说的完整的生命周期图标,并对照以下内容进行阅读。
日常开发中,常用的生命周期方法有:
render()
:渲染组件时调用。当state
和props
发生改变时(当然还有诸如forceUpdate()
等,我们只讲常用的,不常用的不再赘述),会重新调用该方法,以实现组件的重绘。componentDidMount()
:当组件完成挂载时调用。【应用场景:初始化数据,比如从后端API中获取数据、初始化定时器、初始化订阅等】componentWillUnmount()
:当组件即将被卸载时调用。【应用场景:清理资源。比如清除定时器、取消订阅等】
import React from 'react';
class App extends React.Component {
render() {
console.log('render():渲染组件');
return <h1>你好,axum.rs!</h1>;
}
componentDidMount() {
console.log('componentDidMount():组件已挂载');
}
componentWillUnmount() {
console.log('componentWillUnmount():组件即将被卸载');
}
}
export default App;
让函数式组件拥有“生命周期”
React 通过useEffect
hook 让函数式组件拥有近乎生命周期方法的功能。该 hook 比较多形式,我们分别讨论。先看一下它的原型:
useEffect(回调函数[, 监听的 state]);
什么是“监听的 state”
当监听的state
的值发生改变时,才会重新调用回调函数
。如果没有设置该参数,则监听所有state
,如果不想监听任何 state
,请将该参数设置为空数组[]
。
模拟 componentDidMount()
回调函数
的函数体,可以用来模拟 componentDidMount()
。
模拟 componentWillUnmount()
回调函数
的返回值也是一个函数,这个返回值可以用来模拟 componentWillUnmount()
案例:获取客户端IP
本案例将实现,使用 React 从 https://httpbin.org/ip
获取客户端IP。首先,我们直接使用浏览器打开这个网址,可看到返回以下内容:
{
"origin": "具体的IP"
}
流程如下:
- 向
https://httpbin.org/ip
发起GET
请求【componentDidMount()
】 - 将请求的数据进行解析,并保存到组件的状态里【
componentDidMount()
】 - 使用 JSX 显示结果【
render()
】
HTTP 请求依赖库
要发起 HTTP 请求,我们需要安装依赖,这里我们使用 axios
yarn add axios
使用类式组件实现
import axios from 'axios';
import React from 'react';
class App extends React.Component {
state = {
ip: '正在获取',
};
render() {
return <h1>你好,你的IP是:{this.state.ip}</h1>;
}
componentDidMount() {
axios
.get('https://httpbin.org/ip')
.then((resp) => resp.data)
.then((data) => {
this.setState({ ip: data.origin });
})
.catch((err) => {
console.log(err);
});
}
}
export default App;
本节代码:axum-rs-react-lifecycle-get-ip
使用函数式组件实现
import axios from 'axios';
import React, { useEffect, useState } from 'react';
function App() {
const [ip, setIp] = useState('正在获取');
useEffect(() => {
axios
.get('https://httpbin.org/ip')
.then((resp) => resp.data)
.then((data) => {
setIp(data.origin);
})
.catch((err) => {
console.log(err);
});
}, []);
return <h1>你好,你的IP是:{ip}</h1>;
}
export default App;