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

标签 javascript react-native themes

我需要帮助,因为我收到以下错误:警告:无法对未安装的组件执行 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/ */

最佳答案

如果您还不知道 - 您可以在 useEffect Hook 的末尾返回一个函数。每当再次触发该效果时(例如,当其依赖项的值发生更改时)以及组件卸载之前,都会调用该函数。因此,如果您有一个如下所示的 useEffect Hook :

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]);

关于javascript - 无法对未安装的组件主题提供程序执行 React 状态更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58877380/

相关文章:

react-native - 与Signal R相关的功能在Play商店中发布的应用中不起作用

android - navigator.geolocation.getCurrentPosition 在 React Native 中不起作用

reactjs - 如何使 Expo.takeSnapshotAsync 在 Android 上工作

css - 免费的 ASP.Net 和/或 CSS 主题

android - 无法恢复用户上次设置的主题?

android - 对话框中 EditText 的全息主题

javascript - 自定义 Handlebars.js 帮助程序不返回 options.fn

php - 在重载和变慢之前,AJAX 聊天能够在专用服务器上处理多少成员?

javascript - 重置 TinyMCE 框

javascript - 在 Javascript 中将 JSON 转换为 HTML