React 的生命周期指的是组件在创建、更新和销毁的整个过程。在 React 的类组件中,生命周期分为三个主要阶段:
- 挂载(Mounting)
- 更新(Updating)
- 卸载(Unmounting)
如果使用的是函数组件,生命周期是通过 useEffect 以及其他 Hooks 来管理的。
目录
- 1. 挂载阶段(Mounting)
- 2. 更新阶段(Updating)
- 3. 卸载阶段(Unmounting)
- ⚛️ 在函数组件中,如何使用生命周期?
- 前端哪些功能需要关注生命周期?
- 总结
1. 挂载阶段(Mounting)
组件被创建并插入到 DOM 中的阶段。
在类组件中,会触发以下方法:
constructor()static getDerivedStateFromProps(props, state)render()componentDidMount()
详细介绍:
-
constructor(props)- 组件初始化时调用,用于设置初始状态
state或绑定this。 - ⚠️ 不要在这里执行异步操作,适合用于基本的初始化。
- 组件初始化时调用,用于设置初始状态
-
static getDerivedStateFromProps(props, state)- 在
render之前触发,用于根据props更新state,但不常用。 - ⚠️ 这是一个静态方法,不能使用
this!
- 在
-
render()- 组件渲染 UI,必须是纯函数,不能有副作用(如异步请求)。
-
componentDidMount()- 组件挂载后调用,通常用于发送网络请求、订阅事件、操作 DOM 等。
- 适合执行副作用操作(如
setTimeout、setInterval等)。
componentDidMount() {fetch("/api/data").then(response => response.json()).then(data => this.setState({ data })); }
2. 更新阶段(Updating)
组件的 state 或 props 发生变化时,触发更新。
会调用以下方法:
static getDerivedStateFromProps(props, state)shouldComponentUpdate(nextProps, nextState)render()getSnapshotBeforeUpdate(prevProps, prevState)componentDidUpdate(prevProps, prevState, snapshot)
详细介绍:
-
shouldComponentUpdate(nextProps, nextState)- 返回
true组件才会重新渲染,false则阻止更新,提高性能。 - 适用于优化性能,防止不必要的重渲染。
- 返回
-
render()- UI 重新渲染。
-
getSnapshotBeforeUpdate(prevProps, prevState)- 组件更新前的“快照”,常用于获取 DOM 变化前的信息(如滚动位置)。
- 返回值会传递给
componentDidUpdate()。
-
componentDidUpdate(prevProps, prevState, snapshot)- 组件更新完成后执行,适合发送异步请求、更新 DOM。
- ⚠️ 需要注意避免死循环!
- 例如:
componentDidUpdate(prevProps) {if (this.props.userId !== prevProps.userId) {this.fetchUserData();} }
3. 卸载阶段(Unmounting)
组件被从 DOM 中移除时触发。
只有一个方法:
componentWillUnmount()
详细介绍:
-
componentWillUnmount()- 组件销毁前调用,适用于清理副作用,如:
- 清除
setInterval、setTimeout - 取消 API 请求
- 移除事件监听
- 清除
componentWillUnmount() {clearInterval(this.timer); } - 组件销毁前调用,适用于清理副作用,如:
⚛️ 在函数组件中,如何使用生命周期?
React 提供了 useEffect 来代替生命周期方法:
import { useEffect, useState } from "react";function Example() {const [count, setCount] = useState(0);// 相当于 componentDidMount + componentDidUpdateuseEffect(() => {console.log("组件挂载或更新了!");return () => {console.log("组件即将卸载!");};}, [count]); // 只有 count 变化时才会触发return <button onClick={() => setCount(count + 1)}>点击 {count}</button>;
}
useEffect(() => {}, []):只在组件挂载时运行(等价于componentDidMount)。useEffect(() => {}, [变量]):当变量变化时运行(等价于componentDidUpdate)。useEffect(() => { return () => {} }, []):组件卸载时运行(等价于componentWillUnmount)。
前端哪些功能需要关注生命周期?
(一些涉及到内存泄漏的问题)
- 网络请求
componentDidMount()/useEffect(() => {}, []):- 组件加载时请求数据,如用户信息、列表数据。
- 事件监听
-
componentDidMount()/useEffect(() => {... return () => {...} }, []):- 监听键盘事件、窗口大小变化。
- 在
componentWillUnmount()中移除监听 避免内存泄漏。
useEffect(() => {window.addEventListener("resize", handleResize);return () => window.removeEventListener("resize", handleResize); }, []);
- 定时器
componentDidMount()/useEffect(() => {... return () => {...} }, []):setInterval/setTimeout需要在componentWillUnmount()里清除。
- DOM 操作
useEffect(() => {}, [])- 获取滚动位置、测量元素大小。
- 性能优化
shouldComponentUpdate()/React.memo()- 防止组件不必要的重新渲染。
总结
| 生命周期阶段 | 类组件方法 | 函数组件 Hook |
|---|---|---|
| 挂载 | componentDidMount() | useEffect(() => {...}, []) |
| 更新 | componentDidUpdate(prevProps, prevState) | useEffect(() => {...}, [依赖]) |
| 卸载 | componentWillUnmount() | useEffect(() => { return () => {...} }, []) |
如果你用的是函数组件,大部分生命周期操作都可以通过 useEffect 处理。
