如何在 React 中正确地使用 useEffect 处理组件卸载时的清理操作以避免内存泄漏?

如何在 React 中正确地使用 useEffect 处理组件卸载时的清理操作以避免内存泄漏?

在 React 中,useEffect Hook 可以返回一个清理函数,该函数会在组件卸载或下一次 effect 执行前被调用。这是避免内存泄漏(例如订阅、定时器、异步请求等未清理资源)的关键机制。

示例:

import { useEffect, useState } from 'react';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    let isMounted = true; // 标记组件是否仍挂载

    const fetchUser = async () => {
      const data = await fetch(`/api/users/${userId}`).then(res => res.json());
      if (isMounted) {
        setUser(data);
      }
    };

    fetchUser();

    // 清理函数
    return () => {
      isMounted = false;
    };
  }, [userId]);

  return <div>{user ? user.name : 'Loading...'}</div>;
}

解析:

  • 异步操作(如 fetch)在组件卸载后仍可能 resolve,若此时更新状态会引发警告或内存泄漏。
  • 通过设置 isMounted 标志位,仅在组件仍挂载时才更新状态。
  • useEffect 返回的函数会在组件卸载时自动执行,用于取消订阅、清除定时器或标记组件已卸载。
  • 对于定时器、事件监听器等,也应在清理函数中显式移除:
    useEffect(() => {
      const timer = setInterval(() => { /* ... */ }, 1000);
      return () => clearInterval(timer);
    }, []);
    

这种模式确保资源被正确释放,提升应用稳定性和性能。

发表评论 (审核通过后显示评论):

昵称:
邮箱:
内容: