首页 > 解决方案 > React useCallback 内存泄漏卸载组件

问题描述

我是 React 的新手,我收到了这个错误:

警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。

据我了解,似乎我有内存泄漏并且需要对我的 useCallback 挂钩进行 useEffect 清理?

我尝试添加一个useRef来检查挂载,但返回不会将状态更改为 false。


const MyComponent = ({data}) => {
  const mounted = useRef(true);
  const [loading, setLoading] = useState(false);

  const isLoading = useCallback(async () => {
    setLoading(true);

    if (data) {
      console.log('YAY DATA: ', data);
    }

    return () => {
      setLoading(false); // unreachable code
      mounted.current = false; // does this do the cleanup?
    };
  }, [loading]);

  return (
    //...some component
  );
};

export default MyComponent;

标签: reactjsreact-native

解决方案


如果您执行的异步操作在完成后需要为状态设置某些内容,则必须确保在更新状态之前组件仍处于挂载状态。

为了做到这一点,你尝试这样的事情:

const MyComponent = (props) => {
  const mounted = useRef(false);

  useEffect(() => {
        mounted.current = true; // Will set it to true on mount ...
        return () => { mounted.current = false; }; // ... and to false on unmount
  }, []);

  const [loading, setLoading] = useState(false);
  const [data, setData] = useState([]);

  const myAsyncCallback = useCallback(async () => {
    setLoading(true);

    // Await for an async function...
    const data = await yourAsyncFunction(...); // Complete with proper code here

    // While waiting for yourAsyncFunction to be done,
    // It's possible that your component had been unmounted.

    // Therefore, you have to check if the component is still mounted before updating states
    if (mounted.current) { 
      setLoading(false);
      setData(data);
    }
  }, []);

  return (
    //...some component that calls myAsyncCallback
  );
};

export default MyComponent;

推荐阅读