第14章:useEffect Hook
14.1 简要说明:使用useEffect处理副作用
在React函数组件中,useEffect
Hook 是一个强大的工具,用于处理副作用(side effects)。副作用包括数据获取、订阅、DOM操作、定时器等任何需要在组件加载、更新或卸载时完成的操作。
useEffect
的核心作用是:
- 在组件挂载时执行代码(类似于
componentDidMount
)。 - 在组件更新时执行代码(类似于
componentDidUpdate
)。 - 在组件卸载时清理资源(类似于
componentWillUnmount
)。
通过 useEffect
,我们可以避免类组件中的生命周期方法,使函数组件更加简洁和高效。
14.2 useEffect的基本语法
useEffect
的基本语法如下:
useEffect(() => {
// 执行副作用的代码
}, [依赖项]); // 依赖项数组(可选)
- 第一个参数:一个函数,包含要执行的副作用逻辑(如数据获取、订阅等)。当组件挂载时,该函数会被调用。
- 第二个参数(可选):一个包含依赖项的数组。只有当依赖项发生变化时,副作用函数才会重新执行。
示例:简单的useEffect
import React from 'react';
import { useEffect } from 'react';
function Example() {
useEffect(() => {
console.log('Component mounted or updated!');
});
return <div>A simple component</div>;
}
在这个示例中,useEffect
中的代码会在组件挂载和每次更新时执 行。如果没有依赖项数组,useEffect
会在每次渲染时执行。
14.3 依赖项数组的作用
依赖项数组用于控制 useEffect
执行的时机。只有当依赖项数组中的某个值发生变化时,useEffect
中的代码才会重新执行。
示例:依赖项数组的作用
function Example({ count }) {
useEffect(() => {
console.log('Count changed to:', count);
}, [count]); // 只有当count变化时,副作用函数才会执行
return <div>Count: {count}</div>;
}
- 如果不提供依赖项数组,
useEffect
会在每次组件渲染时执行。 - 如果提供空数组
[]
,useEffect
只会在组件挂载时执行一次。
注意点:
- 依赖项数组中的变量必须是影响副作用逻辑的因素。
- 必须明确列出所有依赖项,否则可能导致预期之外的行为。
14.4 清理副作用的方法
在某些情况下,我们需要在组件卸载或副作用函数重新执行之前清理之前的资源。useEffect
允许我们在副作用函数中返回一个清理函数(cleanup function)。
示例:清理计时器
import React, { useEffect } from 'react';
function Timer() {
useEffect(() => {
const timer = setInterval(() => {
console.log('Time updated');
}, 1000);
// 清理函数
return () => {
clearInterval(timer);
console.log('Timer cleared');
};
});
return <div>Timer is running</div>;
}
- 在组件卸载时,
useEffect
会自动调用清理函数,清除计时器。 - 如果依赖项数组中有变化,新的
setInterval
会创建,同时旧的计时器会被清理。
注意点:
- 清理函数只能在
useEffect
的副作用函数中返回。 - 如果没有清理函数可能导致内存泄漏或性能问题。
14.5 综合示例:监听页面大小变化
import React, { useEffect } from 'react';
function ResponsiveComponent() {
useEffect(() => {
const handleResize = () => {
console.log('Window size changed:', window.innerWidth);
};
window.addEventListener('resize', handleResize);
// 清理函数
return () => {
window.removeEventListener('resize', handleResize);
console.log('Event listener removed');
};
}, []);
return <div>Current window width: {window.innerWidth}</div>;
}
在这个示例中:
useEffect
监听窗口大小变化。- 清理函数负责移除事件监听器,防止内存泄漏。
- 依赖项数组为空,因此只有在组件挂载时执行一次。
14.6 总结
useEffect
是处理组件副作用的核心 Hook,能够帮助我们管理数据获取、事件监听、计时器 等操作。通过合理使用依赖项数组和清理函数,我们可以避免常见的内存泄漏问题,并确保组件的高性能运行。
关键点回顾:
useEffect
用于处理副作用(如数据获取、订阅、定时器)。- 依赖项数组控制
useEffect
执行的时机。 - 返回清理函数以释放资源(如清除定时器、移除事件监听)。
通过本章的学习,你应该能够熟练使用 useEffect
Hook 来管理组件的生命周期和副作用。