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
相关产品推荐
相关产品推荐

