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

React深色模式刷新或跳转页面后重置为浅色模式如何解决

问题原因

你的主题状态仅保存在React运行时内存中,页面刷新、组件重新挂载时useState的初始值会被重置为硬编码的"light",自然会丢失用户之前的选择。要实现持久化只需要把用户选择的主题同步到本地存储,初始化时优先读取存储值即可。

实现步骤
  • 初始化theme状态时,优先从localStorage读取之前保存的主题值,如果本地没有存储记录,默认读取系统的深色/浅色模式偏好作为兜底
  • 每次theme更新时,除了修改根节点的类名和样式,同步把最新的主题值写入localStorage
  • 可选优化:在HTML入口文件加一段极小的内联执行脚本,在React资源加载完成前就给根节点设置对应主题类,避免首屏加载时的主题闪烁问题
修改后的完整Hook代码
import React, { useEffect, useState } from "react";

const useDarkMode = () => {
  // 懒初始化状态:仅组件首次挂载时执行一次读取逻辑
  const [theme, setTheme] = useState(() => {
    // 兼容SSR场景,服务端无window对象直接返回默认值
    if (typeof window === "undefined") return "light";
    const storedTheme = window.localStorage.getItem("theme");
    if (storedTheme) return storedTheme;
    // 无本地存储记录时,兜底读取系统主题偏好
    return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
  });
  const colorTheme = theme === "dark" ? "light" : "dark";

  useEffect(() => {
    const root = window.document.documentElement;
    root.classList.remove(colorTheme);
    root.style.colorScheme = theme;
    root.classList.add(theme);
    // 主题变更时同步持久化到本地存储
    window.localStorage.setItem("theme", theme);
  }, [theme, colorTheme]);

  return [colorTheme, setTheme] as const;
};

export default useDarkMode;
可选:解决首屏主题闪烁

如果要完全避免页面刚加载时先显示默认主题、再跳转到用户选择主题的闪烁问题,可以在项目入口index.html的<head>标签内加一段提前执行的内联脚本,不需要等React资源加载完成:

<head>
  <!-- 其他meta、资源标签 -->
  <script>
    (function() {
      const storedTheme = localStorage.getItem('theme');
      const defaultTheme = storedTheme || (matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
      document.documentElement.classList.add(defaultTheme);
      document.documentElement.style.colorScheme = defaultTheme;
    })()
  </script>
</head>

加完这段后,Hook初始化读取的主题和页面提前渲染的主题完全一致,不会出现样式跳变。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 19:21:14