React 生命周期与 Hooks

说明 React 的挂载、更新、卸载阶段如何在类组件生命周期方法和 Hooks 副作用机制中表达。

#tech / dev / frame #resource / react #type / synthesis #status / growing

[!info] related notes

React 生命周期与 Hooks

React 当然有生命周期阶段:挂载、更新、卸载。变化的是,类组件把它们暴露成生命周期方法,函数组件则把相关逻辑改为按依赖和副作用来组织。

范围

这篇只回答三个问题:

  • React 的生命周期阶段还在不在
  • 类组件和函数组件分别怎么表达这些阶段
  • 为什么 useEffect 不是生命周期方法的简单拼接

类组件里的生命周期方法

常见方法:

  • componentDidMount
  • componentDidUpdate
  • componentWillUnmount

较早期、现在不推荐的旧方法:

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

这些方法的共同点是:它们按“发生在什么阶段”来拆分逻辑。

Hooks 时代怎么理解

函数组件没有生命周期方法,但依然有这些阶段。只是你更少去想“我现在在哪个生命周期里”,更多去想:

  • 这段逻辑依赖什么
  • 依赖变了要不要重新同步
  • 之前那次副作用要不要清理

这也是 useEffect 的思维方式。

粗略对应关系

类组件表达Hooks 表达说明
componentDidMountuseEffect(() => {}, [])首次提交后执行一次
componentDidUpdateuseEffect(() => {}, [value])依赖变化后重新执行
componentWillUnmountuseEffect 的 cleanup卸载前或下一次 effect 前清理

但这只是帮助入门的粗略对照,不是严格等价。

为什么不能机械等价

useEffect 的真实语义更接近:

当依赖变化后,执行一段和外部系统同步的逻辑;如果需要,在下一次执行前先清理上一次副作用。

所以它不是 componentDidMount + componentDidUpdate + componentWillUnmount 的简单拼接。

例如:

useEffect(() => {
  const sub = subscribe(id)

  return () => {
    sub.unsubscribe()
  }
}, [id])

这里真正重要的不是“这是挂载还是更新”,而是:

  • id 变了要不要重新订阅
  • 旧订阅要不要先清理
  • 这段逻辑是不是应该放进 effect

一个更准确的心智模型

  • 类组件:按生命周期阶段分散写逻辑
  • 函数组件:按依赖和副作用把相关逻辑聚合在一起

所以 Hooks 没有取消生命周期,而是把生命周期相关逻辑的组织方式换掉了。

常见误解

  • 误解 1:Hooks 时代没有生命周期
  • 误解 2:useEffect 就是所有生命周期方法的总和
  • 误解 3:只要是“挂载后做事”就一定该写进 useEffect

最短记忆方式

React 仍然有挂载、更新、卸载;只是类组件用生命周期方法表达,函数组件用 Hook 和依赖数组表达。

创建于 2026/4/8 更新于 2026/5/27