组件生命周期
本章节将介绍 React 组件的生命周期。在现代函数组件开发中,生命周期主要通过 useEffect 钩子来处理。
1. 生命周期的三个阶段
在 React 组件的整个生命周期中,主要经历以下三个阶段:
- 挂载(Mounting):组件第一次被添加到 DOM。
- 更新(Updating):组件的状态或属性(props)发生变化。
- 卸载(Unmounting):组件从 DOM 中移除。
2. 函数组件与 useEffect
在函数组件中,useEffect 提供了处理这些阶段的统一方式。
实时编辑器
function LifecycleDemo() { const [count, setCount] = useState(0); const [show, setShow] = useState(true); if (!show) return <button onClick={() => setShow(true)}>重新挂载组件</button>; return ( <div style={{ padding: '15px', border: '1px solid #ddd', borderRadius: '8px' }}> <Child count={count} /> <div style={{ display: 'flex', gap: '10px', marginTop: '10px' }}> <button onClick={() => setCount(c => c + 1)}>更新状态 (count: {count})</button> <button onClick={() => setShow(false)} style={{ background: '#ef4444', color: 'white', border: 'none', padding: '4px 8px', borderRadius: '4px' }}> 卸载组件 </button> </div> </div> ); } function Child({ count }) { useEffect(() => { console.log("挂载阶段:组件已进入 DOM"); // 模拟某种副作用,如定时器 const timer = setInterval(() => console.log("计时中..."), 2000); return () => { console.log("卸载阶段:组件已移除,清理资源"); clearInterval(timer); }; }, []); // 空数组表示只在挂载和卸载时执行 useEffect(() => { console.log("更新阶段:count 已变化为 " + count); }, [count]); // 监听 count 的变化 return ( <div style={{ background: '#f0f9ff', padding: '10px' }}> <h4>我是子组件</h4> <p>状态值: <strong>{count}</strong></p> <p>请查看浏览器控制台 (Console) 观察生命周期输出。</p> </div> ); } render(<LifecycleDemo />);
结果
Loading...
3. 类组件的生命周期 (Legacy)
虽然现代 React 推荐使用函数组件,但在阅读旧代码时,你仍会看到以下生命周期方法:
- componentDidMount:挂载后执行(常用于 API 调用)。
- componentDidUpdate:更新后执行(需注意避免无限循环)。
- componentWillUnmount:卸载前执行(清理定时器、解绑事件)。
4. 常见问题:无限循环
如果你的副作用中包含更新状态的逻辑,且没有正确设置依赖数组,组件可能会陷入死循环。
// ❌ 错误做法:没有依赖数组,每次渲染都会触发 useEffect
useEffect(() => {
setCount(count + 1); // 触发重新渲染 -> 触发此 useEffect -> 死循环
});
// ✅ 正确做法:只在挂载时执行
useEffect(() => {
setCount(count + 1);
}, []); // 提供依赖数组
小结
- Mounting(挂载):组件诞生。
- Updating(更新):组件演变。
- Unmounting(卸载):组件消失。
- useEffect:函数组件管理生命周期的核心工具。