React Native+TypeScript:如何持久化深色模式切换状态?
实现深色模式切换状态持久化(使用use-state-persist)
核心修改步骤
- 替换原生
useState为use-state-persist提供的useStatePersist钩子,指定存储key实现持久化 - 确保应用初始化时完成
syncStorage的初始化 - 优化状态更新逻辑避免闭包问题
修改后的完整代码
DarkModeContext.tsx
import React from 'react'; interface DarkMode { isDarkMode: boolean; toggleDarkMode: () => void; } export const DarkModeContext = React.createContext<DarkMode>({} as DarkMode);
app.tsx
import React, { useEffect } from 'react'; import { syncStorage, useStatePersist } from 'use-state-persist'; import { ReactElement } from 'react'; const App: () => ReactElement = () => { // 用useStatePersist替代useState,指定存储key为'darkMode',初始值false const [isDarkMode, setDarkMode] = useStatePersist(false, 'darkMode'); const Drawer = createDrawerNavigator(); // 初始化存储,组件挂载时执行 useEffect(() => { const init = async () => { await syncStorage.init(); }; init(); }, []); // 优化状态切换逻辑,依赖前一个状态值 const toggleDarkMode = () => { setDarkMode(prevMode => !prevMode); }; 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 } 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;
关键说明
- useStatePersist的使用:
useStatePersist(初始值, 存储key)会自动将状态同步到本地存储,重新打开应用时会从存储中读取值初始化状态 - syncStorage初始化:必须在组件挂载时执行
syncStorage.init(),确保存储系统正常工作 - 状态更新逻辑:使用
setDarkMode(prevMode => !prevMode)替代直接依赖isDarkMode,避免因闭包导致的状态更新不及时问题
内容的提问来源于stack exchange,提问作者emma
相关产品推荐
相关产品推荐

