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

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

回答:
在 React 中,当组件卸载时,如果存在异步操作(如 API 请求、定时器、订阅等)仍在进行,可能会尝试更新已卸载组件的状态,从而导致内存泄漏或警告。为避免这种情况,应在 useEffect 的返回函数中执行清理逻辑。

示例:

import { useEffect, useState } from 'react';

function MyComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    let isMounted = true; // 标志位,用于判断组件是否仍挂载

    fetch('/api/data')
      .then(res => res.json())
      .then(result => {
        if (isMounted) {
          setData(result);
        }
      });

    // 清理函数:组件卸载时设置标志位为 false
    return () => {
      isMounted = false;
    };
  }, []);

  return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>;
}

解析:

  • useEffect 的返回函数会在组件卸载(或依赖项变化前)被调用,是执行清理操作的标准方式。
  • 对于异步操作,无法直接“取消” Promise,但可通过 isMounted 标志位判断组件是否仍处于挂载状态,从而避免在卸载后调用 setState。
  • 对于可取消的操作(如 AbortController、WebSocket、定时器等),应在清理函数中主动取消或关闭,例如:
    const controller = new AbortController();
    fetch('/api/data', { signal: controller.signal });
    return () => controller.abort();
    
  • 正确使用清理函数不仅能防止内存泄漏,还能提升应用性能和稳定性。

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

昵称:
邮箱:
内容: