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

如何用TypeScript将暗黑/亮色模式状态持久化到LocalStorage?

解决React Context暗黑模式持久化及TypeScript类型错误问题

核心修复步骤

1. 读取LocalStorage作为初始状态(修复类型错误)

localStorage.getItem('Mode')返回string | null,直接传入JSON.parse会触发类型错误,同时要确保解析后的值是合法的boolean类型,避免非法值导致状态异常。可以封装初始化函数处理:

const getInitialDarkMode = (): boolean => {
  const storedMode = localStorage.getItem('Mode');
  if (storedMode) {
    try {
      const parsedMode = JSON.parse(storedMode);
      // 验证解析结果为boolean,否则返回默认值
      return typeof parsedMode === 'boolean' ? parsedMode : false;
    } catch (e) {
      // 解析失败时返回默认亮色模式
      return false;
    }
  }
  // 无存储值时返回默认值
  return false;
};

在useState中调用该函数作为初始值:

const [darkMode, setDarkMode] = useState(getInitialDarkMode());

2. 模式切换时同步到LocalStorage

每次切换模式后,将最新状态存入LocalStorage,确保刷新页面后状态不丢失,有两种实现方式:

方式一:在切换函数中直接存储

const toggleMode = () => {
  setDarkMode(prevMode => {
    const newMode = !prevMode;
    localStorage.setItem('Mode', JSON.stringify(newMode));
    return newMode;
  });
};

方式二:用useEffect监听状态变化

useEffect(() => {
  // darkMode变化时同步到LocalStorage
  localStorage.setItem('Mode', JSON.stringify(darkMode));
}, [darkMode]);

3. 优化TypeScript类型定义

  • 将TypeContext中的darkMode简化为boolean,与useState类型保持一致:
export interface TypeContext {
  darkMode: boolean;
  setDarkMode: React.Dispatch<React.SetStateAction<boolean>>;
  toggleMode: () => void;
}
  • TypeChildrenProps的children改用React.ReactNode,支持多个子元素、文本等更灵活的场景:
export interface TypeChildrenProps {
  children: React.ReactNode;
}

完整修正代码

import { createContext, useState, useEffect } from "react";

export interface TypeContext {
  darkMode: boolean;
  setDarkMode: React.Dispatch<React.SetStateAction<boolean>>;
  toggleMode: () => void;
}

export interface TypeChildrenProps {
  children: React.ReactNode;
}

export const GlobalThemeContext = createContext<TypeContext>({
  darkMode: false,
  setDarkMode: () => {},
  toggleMode: () => {},
});

const getInitialDarkMode = (): boolean => {
  const storedMode = localStorage.getItem('Mode');
  if (storedMode) {
    try {
      const parsedMode = JSON.parse(storedMode);
      return typeof parsedMode === 'boolean' ? parsedMode : false;
    } catch (e) {
      return false;
    }
  }
  return false;
};

export const ThemeContextProvider = ({ children }: TypeChildrenProps) => {
  const [darkMode, setDarkMode] = useState(getInitialDarkMode());

  useEffect(() => {
    localStorage.setItem('Mode', JSON.stringify(darkMode));
  }, [darkMode]);

  const toggleMode = () => {
    setDarkMode(!darkMode);
  };

  return (
    <GlobalThemeContext.Provider value={{ darkMode, setDarkMode, toggleMode }}>
      {children}
    </GlobalThemeContext.Provider>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:43:15