繁体   English   中英

React Native - 类型脚本:即使在关闭应用程序后,如何保存暗模式切换 state?

[英]React Native - Type Script: How to save dark mode toggle state even after turning off the application?

什么是正确的方法,即使在关闭应用程序后我也可以保存暗模式开关? 我想使用 use-state-persist 库来实现目标。 在我的示例中,我展示了 app.tsx、Preferences.tsx、ViewField.tsx。 这样就可以理解逻辑是如何构建的

DarkModeContext

import React from 'react';

interface DarkMode {
  isDarkMode: boolean;
  setDarkMode: () => void;
}
export const DarkModeContext = React.createContext<DarkMode>({} as DarkMode);

这是 app.tsx

import React, { useEffect, useState } from 'react';
import { syncStorage } from 'use-state-persist';

const App: () => ReactElement = () => {
  const [isDarkMode, setDarkMode] = useState(false);
const Drawer = createDrawerNavigator();
  const initStorage = async () => await syncStorage.init();

const toggleDarkMode = () => {
    setDarkMode(!isDarkMode);
  };

  return (
    <DarkModeContext.Provider value={{ isDarkMode, toggleDarkMode }}>
      <NavigationContainer>
        <Drawer.Navigator
          drawerContent={SideMenu}
          screenOptions={{
            drawerPosition: 'right',
            headerShown: false,
            drawerType: 'front',
          }}
        >
          <Drawer.Screen name='HomeScreen' component={StackNavigator} />
        </Drawer.Navigator>
      </NavigationContainer>
    </DarkModeContext.Provider>
  );
};
export default App;

这是 Preferences.tsx

import React, { useContext, useState } from 'react';
import ViewField from './ViewField';
import { DarkModeContext } from '~/context/DarkModeContext';
const Preferences = () => {
  const { isDarkMode, toggleDarkMode } = useContext(DarkModeContext);

 return (
      <View>
 <ViewField title='dark mode' isEnabled={isDarkMode} setValue={toggleDarkMode} />
</View>
  );
};

export default Preferences;

这是 ViewField.tsx

import { View, Text, Switch } from 'react-native';
import React from 'react';
import styles from './ViewFieldStyles';
import { useContext } from 'react';
import { DarkModeContext } from '~/context/DarkModeContext';

type Props = {
  title: string;
  isEnabled: boolean;
  setValue: () => void;
};
const ViewField = ({ title, isEnabled, setValue }: Props) => {
  const { isDarkMode } = useContext(DarkModeContext);

 return (
    <View style={isDarkMode ? styles.optionViewDark : styles.optionView}>
      <View style={styles.sameRowTextView}>
        <Text style={isDarkMode ? styles.optionTextDark : styles.optionText}>{title}</Text>
        <View style={styles.switchView}>
          <Switch
            trackColor={
              isDarkMode
                ? { false: 'rgba(255, 255, 255, 0.38)', true: 'rgba(187, 134, 252, 0.38)' }
                : { false: '#767577', true: 'rgba(4, 76, 163, 0.38)' }
            }
onValueChange={setValue}
            value={isEnabled}
          />
        </View>
      </View>
    </View>
  );
};

export default ViewField;

请记住,使用Boolean values的 use-state-persist 似乎存在一些问题。 此外,该库的最新发布版本是从 2020 年开始的。

但是, use-state-persist库似乎只是AsyncStorage的一个包装器,它维护得很好。 我鼓励你改用这个库。

在您的情况下,可以按如下方式实现:

  • 将 state 的实际设置器存储在上下文中,
  • 创建一个在应用程序挂载时访问异步存储的效果:如果存在对应键的值,则设置上下文的 state,如果不存在,则不执行任何操作。
  • Preferences组件中,将新的 state 也存储在异步存储中。
const App: () => ReactElement = () => {
  const [isDarkMode, setDarkMode] = useState(false);

  const contextValue = React.useMemo(() => ({
      isDarkMode,
      setDarkMode
  }), [isDarkMode])

  React.useEffect(() => {
    const load = async () => {
        const value = await AsyncStorage.getItem('isDarkMode');
        if (value !== null) {
            setDarkMode(JSON.parse(value));
        }
    }
    load();
  }, [])


  return (
    <DarkModeContext.Provider value={contextValue}>

   ...
};

Preferences组件中,设置 state 并将其保存到本地存储。

const Preferences = () => {
   const { isDarkMode, setDarkMode } = useContext(DarkModeContext);

   async function toggle() {
     const newValue = JSON.stringify(!isDarkMode);
     await AsyncStorage.setItem('isDarkMode', newValue);
     setDarkMode(prev => !prev);
   }

   return (
      <View>
        <ViewField title='dark mode' isEnabled={isDarkMode} setValue={toggle} />
      </View>
   );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM