React 组件的生命周期描述了组件从创建到销毁的整个过程。在 React 16.3 版本之后,生命周期方法发生了重要更新,引入了新的静态生命周期方法,并标记了一些旧方法为不安全(即将废弃)。
以下是 React 类组件生命周期的三个主要阶段及其对应的生命周期函数:
阶段一:挂载阶段 (Mounting)
组件被创建并插入到 DOM 中。
| 生命周期函数 | 说明 |
|---|---|
constructor(props) | 初始化:组件构造函数,用于初始化 state 和绑定事件处理函数。必须调用 super(props)。 |
static getDerivedStateFromProps(props, state) | 状态派生:在 render 之前调用,用于根据 props 更新 state。返回一个对象来更新 state,或返回 null 不更新。很少使用。 |
render() | 渲染:唯一必需的方法。返回 JSX,描述 UI 结构。必须是纯函数,不能修改 state 或与 DOM 交互。 |
componentDidMount() | 挂载完成:组件已插入 DOM。适合进行数据获取 (API 调用)、设置定时器、操作 DOM 等操作。 |
执行顺序:
constructor→getDerivedStateFromProps→render→componentDidMount
阶段二:更新阶段 (Updating)
当 props 或 state 发生变化时,组件重新渲染。
| 生命周期函数 | 说明 |
|---|---|
static getDerivedStateFromProps(props, state) | 在 render 之前调用,用于根据新的 props 同步更新 state。 |
shouldComponentUpdate(nextProps, nextState) | 性能优化:决定组件是否需要重新渲染。返回 true(默认)则继续,返回 false 则跳过更新。常用于 React.PureComponent 或手动优化。 |
render() | 重新渲染组件。 |
getSnapshotBeforeUpdate(prevProps, prevState) | 获取快照:在 DOM 更新前被调用,可以读取 DOM 的当前状态(如滚动位置)。返回的值会作为第三个参数传递给 componentDidUpdate。 |
componentDidUpdate(prevProps, prevState, snapshot) | 更新完成:组件已更新并重新渲染到 DOM。适合进行DOM 操作、网络请求(需对比 props 防止无限循环)。 |
执行顺序:
getDerivedStateFromProps→shouldComponentUpdate→render→getSnapshotBeforeUpdate→componentDidUpdate
阶段三:卸载阶段 (Unmounting)
组件从 DOM 中被移除。
| 生命周期函数 | 说明 |
|---|---|
componentWillUnmount() | 清理工作:在组件卸载和销毁前调用。必须在此方法中清理副作用,如:清除定时器、取消网络请求、移除事件监听器、清理订阅等。 |
已废弃或即将废弃的生命周期方法(不推荐使用)
这些方法在异步渲染中可能导致问题,React 16.3+ 已标记为不安全。
| 旧方法 | 问题 | 替代方案 |
|---|---|---|
componentWillMount() | 已移除。 | 使用 constructor 或 componentDidMount。 |
componentWillReceiveProps(nextProps) | 在 props 更新时调用,但容易误用导致状态不一致。 | 使用 getDerivedStateFromProps 或 useEffect(函数组件)。 |
componentWillUpdate(nextProps, nextState) | 在更新前调用,但不允许修改 state。 | 使用 getSnapshotBeforeUpdate。 |
注意:在 React 17+ 中,这些方法需要加上
UNSAFE_前缀才能使用(如UNSAFE_componentWillMount),以警示开发者。
错误处理阶段 (Error Handling)
当渲染过程、生命周期方法或子组件构造函数中发生错误时。
| 生命周期函数 | 说明 |
|---|---|
static getDerivedStateFromError(error) | 在后代组件抛出错误后调用。返回一个对象来更新 state,用于渲染降级 UI(如错误提示)。 |
componentDidCatch(error, info) | 在后代组件出错后调用。适合记录错误日志。 |
函数组件中的“生命周期”
函数组件没有传统生命周期方法,但通过 useEffect Hook 可以模拟所有生命周期行为:
import { useEffect, useState } from 'react';
function MyComponent({ userId }) {
const [data, setData] = useState(null);
// 模拟 componentDidMount + componentDidUpdate
useEffect(() => {
// 挂载后和更新时执行(类似 componentDidMount 和 componentDidUpdate)
fetchData(userId).then(setData);
// 清理函数(模拟 componentWillUnmount)
return () => {
// 清理副作用,如取消请求
};
}, [userId]); // 依赖数组:仅当 userId 变化时重新执行
// 模拟 componentDidMount
useEffect(() => {
// 只在挂载后执行一次
console.log('组件已挂载');
}, []); // 空依赖数组
return <div>{data}</div>;
}
总结
| 阶段 | 推荐使用的生命周期函数 |
|---|---|
| 挂载 | constructor, getDerivedStateFromProps, render, componentDidMount |
| 更新 | getDerivedStateFromProps, shouldComponentUpdate, render, getSnapshotBeforeUpdate, componentDidUpdate |
| 卸载 | componentWillUnmount |
| 错误处理 | getDerivedStateFromError, componentDidCatch |
核心要点:
- 优先使用
getDerivedStateFromProps和getSnapshotBeforeUpdate替代旧的UNSAFE_*方法。 useEffect是函数组件中管理副作用和生命周期逻辑的现代方式。- 始终在
componentWillUnmount中清理副作用,防止内存泄漏。
THE END


