如何为React主题切换器实现Local Storage,刷新时保留主题?
问题:React主题切换器无法实现Local Storage功能
我无法在我的主题切换器应用中实现Local Storage功能,希望能获得相关帮助
我的代码如下:
import React, { useState } from 'react'; import Header from './components/Header'; import Main from './components/Main'; import themes from './utils/themes'; const App = () => { const [theme, setTheme] = useState(''); const handleChange = (selectedTheme) => { setTheme(themes[selectedTheme.value]); }; const refCallback = (node) => { if (node) { theme && Object.keys(theme).forEach((element) => { node.style.setProperty(element, theme[element], 'important'); if (element === 'background-color' || element === 'background') { // apply the same background mentioned for theme to the body of the website document.body.style.background = theme[element]; } }); } }; return ( <div ref={refCallback} className="main-section"> <Header handleChange={handleChange} /> <Main /> </div> ); }; export default App;
据我理解,我需要将初始值保存到Local Storage中,并在切换主题时对其进行修改
解决方案
要实现主题的Local Storage持久化,直接按以下步骤修改代码即可:
从Local Storage初始化主题状态
将useState的初始值改为从Local Storage读取,没有保存值时使用默认主题(假设你的themes对象里有light作为默认项):const [theme, setTheme] = useState(() => { // 读取本地存储的主题键名 const savedThemeKey = localStorage.getItem('selectedTheme'); // 有保存值则返回对应主题,否则返回默认主题 return savedThemeKey ? themes[savedThemeKey] : themes.light; });切换主题时同步保存到Local Storage
修改handleChange函数,在更新状态的同时把选中的主题键名存入Local Storage:const handleChange = (selectedTheme) => { const newTheme = themes[selectedTheme.value]; setTheme(newTheme); // 保存主题键名,供下次初始化读取 localStorage.setItem('selectedTheme', selectedTheme.value); };优化主题应用逻辑(可选)
把当前的refCallback替换为useEffect,组件挂载和主题变化时自动应用样式,逻辑更清晰:import React, { useState, useEffect } from 'react'; // ...其他代码不变 useEffect(() => { if (!theme) return; const root = document.querySelector('.main-section'); Object.keys(theme).forEach((element) => { root.style.setProperty(element, theme[element], 'important'); if (element === 'background-color' || element === 'background') { document.body.style.background = theme[element]; } }); }, [theme]); // 移除return中的ref属性 return ( <div className="main-section"> <Header handleChange={handleChange} /> <Main /> </div> );
修改完成后,用户刷新页面或重新打开应用时,上次选中的主题会自动加载。
内容的提问来源于stack exchange,提问作者Samson Njuguna
相关产品推荐
相关产品推荐

