React类组件的生命周期方法有哪些?
好的,我们来详细梳理一下 React 类组件的生命周期方法。
React 类组件的生命周期可以分为三个主要阶段:挂载(Mounting)、更新(Updating)和卸载(Unmounting)。此外,还有一个特殊的错误处理阶段。
下图清晰地展示了这些生命周期方法的执行顺序和所属阶段:
flowchart TD
A[类组件实例化] --> B[“constructor<br>构造函数”]
B --> C[“static getDerivedStateFromProps<br>派生状态”]
C --> D[“render<br>渲染”]
D --> E[“componentDidMount<br>挂载完成”]
E -- 状态/属性变化 --> F{是否应更新?}
F -- No --> G[跳过更新]
F -- Yes --> H[“static getDerivedStateFromProps<br>派生状态”]
H --> I[“shouldComponentUpdate<br>是否继续?”]
I -- No / False --> J[跳过渲染与提交]
I -- Yes / True --> K[“render<br>重新渲染”]
K --> L[“getSnapshotBeforeUpdate<br>获取快照”]
L --> M[DOM 已更新]
M --> N[“componentDidUpdate<br>更新完成”]
subgraph Z [卸载阶段]
direction TB
O["componentWillUnmount<br>(清理工作)"]
end
E -.-> Z
P{发生错误} -.-> Q["static getDerivedStateFromError"]
P -.-> R["componentDidCatch"]
一、挂载阶段 (Mounting)
当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:
constructor(props)- 调用时机:在组件挂载之前被调用。
- 用途:
- 初始化
state。 - 绑定事件处理函数的
this。 - 注意:如果不需要初始化 state 或绑定方法,则不需要实现 constructor。
- 初始化
static getDerivedStateFromProps(props, state)- 调用时机:在调用
render方法之前调用,无论是首次挂载还是后续更新,都会触发此方法。 - 用途:让组件在
props变化时更新其内部state。它应返回一个对象来更新 state,或者返回null表示不更新。 - 特点:这是一个静态方法,没有
this,无法访问到组件的实例。目前使用较少且容易出错,通常建议使用其他方式替代。
- 调用时机:在调用
render()- 调用时机:这是 class 组件中唯一必须实现的方法。它在
getDerivedStateFromProps之后、以及后续的 props/state/forceUpdate() 改变时被调用。 - 用途:根据组件的 props 和 state,生成并返回 JSX(即虚拟 DOM)。此时不应进行任何副作用操作(如数据请求、订阅等)。
- 调用时机:这是 class 组件中唯一必须实现的方法。它在
componentDidMount()- 调用时机:在组件挂载(插入 DOM树)后立即调用。此时已经可以获取到真实的 DOM。
- -用途:
* 进行网络请求(API Fetch)。
-设置订阅或事件监听器。
-操作真实 DOM。
-设置基于 DOM的第三方库初始化。
###二、更新阶段 (Updating)
当组件的 props 或 state发生变化时,会进入更新阶段。其生命周期顺序如下:
1.** static getDerivedStateFromProps(props, state) ``
同挂载阶段的该方法描述一致。*
2. shouldComponentUpdate(nextProps, nextState)``
- -调用时机:在接收到新的 props或state后,
render方法之前被调用。
-返回值:布尔值。true(默认)表示允许继续渲染;false表示阻止本次渲染,可用于性能优化。
-注意:首次渲染或使用 forceUpdate()时不会触发此方法。
3. render() `` *同挂载阶段的该方法描述一致。
4. getSnapshotBeforeUpdate(prevProps, prevState)``
- -调用时机:在最近一次渲染输出(提交到DOM节点)之前被调用于此方法中读取当前DOM的状态非常安全因为它发生在潜在DOM变更前但在此之后实际DOM已被更改了.
-返回值:传递给 componentDidUpdate`.通常用作捕获滚动位置等信息.
5. componentDidUpdate(prevProps, prevState, snapshot)``
- -调用时机:在更新完成后立即被调用于此方法中可执行依赖于新DOM的操作或进行网络请求(但需比较新旧props避免无限循环)。参数snapshot是上一步getSnapshotBeforeUpdate的返回值.
###三、卸载阶段 (Unmounting)
当组件从DOM中移除时会进入此阶段:
1. componentWillUnmount()``
- -调用时机:在组件卸载及销毁之前直接被调用于此处应执行所有必要的清理操作例如:
清除定时器取消网络请求移除事件监听器取消订阅防止内存泄漏.
###四、错误处理阶段 (Error Handling)
当子组件中抛出错误或执行异步操作时出现错误会被触发:
1. static getDerivedStateFromError(error)``
作用:捕获后代组件抛出的错误并更新state以显示降级UI.*
特点:静态方法无this返回对象来更新state.*
2. componentDidCatch(error, errorInfo)``
作用:捕获后代组件的错误并进行日志记录等操作.
特点:可以执行副作用操作如记录错误信息到服务器.*
总结表格:
| 类别 | 生命周期方法 | 说明 |
|---|---|---|
| 挂载 | constructor() |
初始化状态和绑定事件 |
static getDerivedStateFromProps() |
根据props派生state | |
render() |
渲染JSX | |
componentDidMount() |
进行副作用操作(数据请求/DOM操作) | |
| 更新 | static getDerivedStateFromProps() |
同上 |
shouldComponentUpdate() |
控制是否重新渲染优化性能 | |
render() |
同上 | |
getSnapshotBeforeUpdate() |
获取DOM信息传递给下个生命周期 | |
componentDidUpdate() |
处理依赖新DOM的副作用 | |
| 卸载 | componentWillUnmount() |
清理资源防止内存泄漏 |
| 错误处理 | static getDerivedStateFromError() |
显示错误UI |
componentDidCatch() |
记录错误信息 |
随着 React Hooks普及函数式组件通过useEffect等Hook可以更简洁地管理类似逻辑因此在新项目中更推荐使用函数式+Hooks方式但在维护旧项目时理解类生命周期依然至关重要.*