React useCallback 内存泄漏卸载组件

IT技术 reactjs react-native
2021-05-11 21:13:16

我是 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;

2个回答

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

为此,您可以尝试以下操作:

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;

由于 useEffect cleanUp 在组件卸载时,您无法更新状态(并且因为它卸载了可以存储值的位置)

您的代码似乎是在 useEffect 中完成 api 调用的代码。就像那样:

useEffect(() => {
    let mounted = true
    fetchAPI.then(() => {
        if (mounted) {
            setloading(false)
        }
    })

    return function cleanup() {
        mounted = false
    }
}, [])

如果是这样,请看这里:https : //dev.to/otamnitram/react-useeffect-cleanup-how-and-when-to-use-it-2hbm