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

React中如何实现网站主题刷新后持久化?

问题诊断与修复方案

核心问题分析

你的代码里有两个关键错误导致主题无法持久化:

  • localStorage读取键名错误:localStorage.getItem(theme) 这里把当前theme变量的值当成了键名,而不是固定的'theme'键,导致每次都读不到正确的存储值。
  • useEffect逻辑混乱:当前的useEffect不仅没有正确同步主题到localStorage,反而在每次theme变化时做了多余的判断和重复设置,甚至可能触发不必要的状态更新循环。

修复后的代码

import { WeatherApi } from "./pages/home/weather-api";
import '../src/App.scss'
import { createContext, useEffect, useState } from "react";
import ReactSwitch from "react-switch";

export const ThemeContext = createContext({})

function App() {
  // 初始从localStorage获取主题,默认light
  const [theme, setTheme] = useState<string>(localStorage.getItem('theme') || 'light')

  // 当theme变化时,同步更新到localStorage
  useEffect(() => {
    localStorage.setItem('theme', theme)
  }, [theme])

  const toggleTheme = () => {
    setTheme(currentTheme => currentTheme === "light" ? "dark" : "light")
  }

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      <div className="App" id={theme}>
        <WeatherApi />
        <div className="switch">
          <label>{theme === "light" ? "Light mode" : "Dark mode"}</label>
          <ReactSwitch onChange={toggleTheme} checked={theme === "dark"} />
        </div>
      </div>
    </ThemeContext.Provider>
  )
}

export default App;

关键修复点说明

  • 修正存储读取逻辑:初始状态直接用localStorage.getItem('theme')获取正确的存储值,不需要在useEffect里重复读取判断。
  • 简化useEffect职责:让useEffect只负责在theme状态变化时,将新的主题值同步到localStorage,确保状态和存储一致。
  • 移除冗余代码:删掉了useEffect里那些会导致状态混乱的判断和重复设置,避免触发不必要的重渲染。

这样修改后,切换主题时localStorage会正确更新,页面刷新时也会从localStorage读取上次保存的主题,实现持久化效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:48:11