无法对未安装的组件主题提供程序执行 React 状态更新

Can't perform a React state update on an unmounted component theme provider

我需要帮助,因为我收到以下错误:警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 componentWillUnmount 方法中的所有订阅和异步任务。在 createCategory 中(在 themeProvider.js:39)

/* Imports */
    import React, { useContext, useState, useEffect } from 'react';
    import AsyncStorage from '@react-native-community/async-storage';
    import THEMES from '@app/theme/themes.json';
    /* /Imports/ */

    const STORAGE_KEY = 'THEME_ID';
    const ThemeContext = React.createContext();

    /* Exports */
    export const ThemeContextProvider = ({ children }) => {
      const [themeID, setThemeID] = useState();

      useEffect(() => {
        (async () => {
          const storedThemeID = await AsyncStorage.getItem(STORAGE_KEY);
          if (storedThemeID) setThemeID(storedThemeID);
          else setThemeID(THEMES[1].key);
        })();
      }, []);

      return (
        <ThemeContext.Provider value={{ themeID, setThemeID }}>
          {!!themeID ? children : null}
        </ThemeContext.Provider>
      );
    };

    export function withTheme(Component) {
      function TargetComponent(props) {
        const { themeID, setThemeID } = useContext(ThemeContext);
        const getTheme = themeID => THEMES.find(theme => theme.key === themeID);
        const setTheme = themeID => {
          AsyncStorage.setItem(STORAGE_KEY, themeID);
          setThemeID(themeID);
        };

        return (
          <Component
            {...props}
            themes={THEMES}
            theme={getTheme(themeID)}
            setTheme={setTheme}
          />
        );
      }

      TargetComponent.navigationOptions = Component.navigationOptions;

      return TargetComponent;
      }
    /* /Exports/ */

如果您还不知道 - 您可以 return 在 useEffect 挂钩的末尾添加一个函数。每当再次触发该效果时(例如,当其依赖项的值发生更改时)以及组件卸载之前,都会调用该函数。所以如果你有一个像这样的 useEffect 钩子:

useEffect(() => {
  // logic here

  return () => {
    // clean up
  };
}, []); // no dependencies!

相当于:

class SomeComponent extends React.Component {
  componentDidMount() {
    // logic here
  }

  componentWillUnmount() {
    // clean up
  }
}

所以我会在你的代码中添加:

useEffect(() => {
  let isCancelled = false;
  const fetchData = async () => {
    try {
      // fetch logic omitted...
      const data = await AsyncStorage.getItem(STORAGE_KEY);

      if (storedThemeID) setThemeID(storedThemeID);
      else setThemeID(THEMES[1].key);
    } catch (e) {
      throw new Error(e)
    }
  };

  fetchData();

  return () => {
    isCancelled = true;
  };
}, [themeID]);

试试这个

let unmounted = false;

useEffect(() => {
    (async () => {
        const storedThemeID = await AsyncStorage.getItem(STORAGE_KEY);
        if (!unmounted) {
            if (storedThemeID) setThemeID(storedThemeID);
            else setThemeID(THEMES[1].key);
        }
    })();
    return () => {
        unmounted = true;
    };
}, []);