跳到主要内容

第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,能够帮助我们管理数据获取、事件监听、计时器等操作。通过合理使用依赖项数组和清理函数,我们可以避免常见的内存泄漏问题,并确保组件的高性能运行。

关键点回顾

  1. useEffect 用于处理副作用(如数据获取、订阅、定时器)。
  2. 依赖项数组控制 useEffect 执行的时机。
  3. 返回清理函数以释放资源(如清除定时器、移除事件监听)。

通过本章的学习,你应该能够熟练使用 useEffect Hook 来管理组件的生命周期和副作用。