如何使用AsyncStorage存储和获取主题状态

问题描述

我想将主题状态存储在应用程序中,以便所选主题在应用程序关闭后将保持不变。我有两个文件一个是具有导航的App.js文件,另一个是具有抽屉内容以及主题开关的DrawerContent.js文件toggleTheme通过DrawerContent传递到useContext

这些是App文件摘要

import {
  NavigationContainer,DefaultTheme as NavigationDefaultTheme,DarkTheme as NavigationDarkTheme
} from '@react-navigation/native';
import {
  Provider as PaperProvider,DefaultTheme as PaperDefaultTheme,DarkTheme as PaperDarkTheme
} from 'react-native-paper';
import AsyncStorage from '@react-native-community/async-storage';

const THEME_KEY = 'theme_color';

export default function App() {
  const [isDarkTheme,setIsDarkTheme] = useState(false);

  {/* Themes */ }
  const CustomDefaultTheme = {
    ...NavigationDefaultTheme,...PaperDefaultTheme,colors: {
      ...NavigationDefaultTheme.colors,...PaperDefaultTheme.colors,background: '#ffffff',text: '#333333',tab: '#0789DC'
    }
  }

  const CustomDarkTheme = {
    ...NavigationDarkTheme,...PaperDarkTheme,colors: {
      ...NavigationDarkTheme.colors,...PaperDarkTheme.colors,background: '#333333',text: '#ffffff',tab: '#2c3e50'
    }
  }

  const theme = isDarkTheme ? CustomDarkTheme : CustomDefaultTheme;

  // AsyncSotrage
  const storeTheme = async (key,isDarkTheme) => {
    try {
      await AsyncStorage.setItem(THEME_KEY,JSON.stringify(isDarkTheme))
      setIsDarkTheme(isDarkTheme);
      console.log(isDarkTheme)
    } catch (error) {
      alert(error);
    }
  }

  const getTheme = async () => {
    try {
      const savedTheme = await AsyncStorage.getItem(THEME_KEY)
      if (savedTheme !== null) {
        setIsDarkTheme(JSON.parse(savedTheme));
      }
    } catch (error) {
      alert(error);
    }
  }


  const authContext = useMemo(() => ({
    toggleTheme: () => {
      setIsDarkTheme(isDarkTheme => !isDarkTheme);
      //  storeTheme(isDarkTheme => !isDarkTheme);
      console.log(isDarkTheme);
    }
  }),[]
  );


  useEffect(() => {
    getTheme();

    // Fetch the token from storage then navigate to our appropriate place
    const bootstrapAsync = async () => {
      let userToken;

      try {
        userToken = await AsyncStorage.getItem(USER_TOKEN)
        if (userToken !== null) {
          setUserToken(JSON.parse(userToken))
        }
      } catch (e) {
        alert(e)
      }

      // After restoring token,we may need to validate it in production apps

      // This will switch to the App screen or Auth screen and this loading
      // screen will be unmounted and thrown away.
      dispatch({ type: 'RESTORE_TOKEN',token: userToken });
    };

    bootstrapAsync();

  },[]);


  return (
    <PaperProvider theme={theme}>
      <AuthContext.Provider value={authContext}>
        <NavigationContainer theme={theme}>
          ...
        </NavigationContainer>
      </AuthContext.Provider>
    </PaperProvider>
  )
}

这是DrawerContent代码

import {
  useTheme,Avatar,Title,Caption,Paragraph,Drawer,Text,TouchableRipple,Switch
} from 'react-native-paper';

export function DrawerContent(props) {

  const paperTheme = useTheme();
  const { signOut,toggleTheme } = React.useContext(AuthContext);


  return (
    <View style={{ flex: 1 }}>
      <DrawerContentScrollView>
        <View style={styles.drawerContent}>
            ...
          <Drawer.Section title="Preferences">
            <TouchableRipple onPress={() => { toggleTheme() }}>
              <View style={styles.preference}>
                <Text>Dark Theme</Text>
                <View pointerEvents="none">
                  <Switch
                    value={paperTheme.dark}
                  />
                </View>
              </View>
            </TouchableRipple>
          </Drawer.Section>
        </View>
      </DrawerContentScrollView>
    </View>
  )
}

解决方法

也许AsyncStorage的有效同步访问可以解决您的问题。建议您使用react-native-easy-app开放源代码库react-native-easy-app,通过它您可以访问AsyncStorage中的任何数据(如内存对象)。

对于特定用法,也许您可​​以在Project StorageController中引用Sample_Hook文件