函数组件与类组件生命周期
在 React 函数组件中,生命周期的概念与类组件有所不同。函数组件没有像类组件那样的生命周期方法(如 componentDidMount
、componentDidUpdate
等),而是通过 Hooks 来模拟生命周期的行为。最常用的 Hook 是 useEffect
,它可以覆盖大部分生命周期场景。
1. 函数组件的“生命周期”
函数组件的生命周期可以分为以下几个阶段:
- 挂载阶段(Mount):组件被创建并插入到 DOM 中。
- 更新阶段(Update):组件的状态或 props 发生变化,重新渲染。
- 卸载阶段(Unmount):组件从 DOM 中移除。
2. 使用 useEffect
模拟生命周期
useEffect
是 React 提供的一个 Hook,用于在函数组件中执行副作用操作(如数据获取、DOM 操作等)。通过配置 useEffect
的依赖项,可以模拟生命周期的不同阶段。
基本语法:
useEffect(() => {
// 副作用逻辑
return () => {
// 清理逻辑(可选)
};
}, [dependencies]); // 依赖项数组
- 副作用逻辑:在组件挂载或更新时执行。
- 清理逻辑:在组件卸载或下一次副作用执行前执行。
- 依赖项数组:决定副作用何时触发。
3. 模拟生命周期阶段
(1) 挂载阶段(componentDidMount)
在组件挂载时执行某些操作(如数据获取、事件监听)。
useEffect(() => {
console.log('组件挂载完成');
// 在这里执行挂载时的操作,比如数据获取
fetchData();
// 返回的清理函数会在组件卸载时执行
return () => {
console.log('组件卸载');
};
}, []); // 空数组表示只在挂载和卸载时执行
- 空依赖项数组
[]
:表示副作用只在挂载和卸载时执行。 - 清理函数:在组件卸载时执行,用于清除副作用(如取消订阅、移除事件监听器)。
(2) 更新阶段(componentDidUpdate)
在组件更新时执行某些操作(如根据 props 或 state 的变化更新数据)。
useEffect(() => {
console.log('组件更新完成');
// 在这里执行更新时的操作
updateData();
}, [props, state]); // 依赖项数组,当 props 或 state 变化时触发
- 依赖项数组
[props, state]
:表示当props
或state
变化时,副作用会重新执行。 - 如果没有依赖项数组,副作用会在每次渲染后都执行。
(3) 卸载阶段(componentWillUnmount)
在组件卸载时执行清理操作(如取消网络请求、移除事件监听器)。
useEffect(() => {
const handleResize = () => {
console.log('窗口大小改变');
};
window.addEventListener('resize', handleResize);
// 返回的清理函数会在组件卸载时执行
return () => {
window.removeEventListener('resize', handleResize);
};
}, []); // 空数组表示只在挂载和卸载时执行
- 清理函数:在组件卸载时执行,用于清除副作用。
4. 其他生命周期场景
(1) 只在挂载时执行
如果只想在挂载时执行某些操作,可以使用空依赖项数组 []
。
useEffect(() => {
console.log('只在挂载时执行');
}, []); // 空数组
(2) 每次渲染后都执行
如果不传递依赖项数组,副作用会在每次渲染后都执行。
useEffect(() => {
console.log('每次渲染后都执行');
}); // 没有依赖项数组
(3) 根据特定状态或 props 变化执行
通过指定依赖项数组,可以控制副作用在特定状态或 props 变化时执行。
useEffect(() => {
console.log('count 发生变化时执行');
}, [count]); // 依赖项数组
5. 完整的生命周期示例
以下是一个完整的示例,展示如何在函数组件中模拟生命周期:
import React, { useState, useEffect } from 'react';
function MyComponent({ initialCount }) {
const [count, setCount] = useState(initialCount);
// 挂载阶段
useEffect(() => {
console.log('组件挂载完成');
// 清理函数(卸载阶段)
return () => {
console.log('组件卸载');
};
}, []);
// 更新阶段(当 count 变化时)
useEffect(() => {
console.log('count 更新完成:', count);
}, [count]);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default MyComponent;
6. 总结
在 React 函数组件中,生命周期主要通过 useEffect
来模拟:
生命周期阶段 | 类组件方法 | 函数组件实现方式 |
---|---|---|
挂载阶段 | componentDidMount | useEffect(() => {}, []) |
更新阶段 | componentDidUpdate | useEffect(() => {}, [dependencies]) |
卸载阶段 | componentWillUnmount | useEffect(() => { return () => {} }, []) |