You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;

关键说明

  1. useStatePersist的使用:useStatePersist(初始值, 存储key)会自动将状态同步到本地存储,重新打开应用时会从存储中读取值初始化状态
  2. syncStorage初始化:必须在组件挂载时执行syncStorage.init(),确保存储系统正常工作
  3. 状态更新逻辑:使用setDarkMode(prevMode => !prevMode)替代直接依赖isDarkMode,避免因闭包导致的状态更新不及时问题

内容的提问来源于stack exchange,提问作者emma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 15:25:44