React 生命周期与 Hooks
说明 React 的挂载、更新、卸载阶段如何在类组件生命周期方法和 Hooks 副作用机制中表达。
#tech / dev / frame
#resource / react
#type / synthesis
#status / growing
[!info] related notes
React 生命周期与 Hooks
React 当然有生命周期阶段:挂载、更新、卸载。变化的是,类组件把它们暴露成生命周期方法,函数组件则把相关逻辑改为按依赖和副作用来组织。
范围
这篇只回答三个问题:
- React 的生命周期阶段还在不在
- 类组件和函数组件分别怎么表达这些阶段
- 为什么
useEffect不是生命周期方法的简单拼接
类组件里的生命周期方法
常见方法:
componentDidMountcomponentDidUpdatecomponentWillUnmount
较早期、现在不推荐的旧方法:
componentWillMountcomponentWillReceivePropscomponentWillUpdate
这些方法的共同点是:它们按“发生在什么阶段”来拆分逻辑。
Hooks 时代怎么理解
函数组件没有生命周期方法,但依然有这些阶段。只是你更少去想“我现在在哪个生命周期里”,更多去想:
- 这段逻辑依赖什么
- 依赖变了要不要重新同步
- 之前那次副作用要不要清理
这也是 useEffect 的思维方式。
粗略对应关系
| 类组件表达 | Hooks 表达 | 说明 |
|---|---|---|
componentDidMount | useEffect(() => {}, []) | 首次提交后执行一次 |
componentDidUpdate | useEffect(() => {}, [value]) | 依赖变化后重新执行 |
componentWillUnmount | useEffect 的 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 和依赖数组表达。