如何将React明暗模式逻辑迁移至Context文件?
迁移明暗模式至React Context的解决方法
1. 新建ThemeContext及Provider组件
把明暗模式的状态逻辑全部迁移到Context的Provider中,同时将状态和更新方法暴露给子组件:
// src/contexts/ThemeContext.js import { createContext, useContext, useState, useEffect } from 'react'; const ThemeContext = createContext(); export function ThemeProvider({ children }) { const [lightMode, setLightMode] = useState(false); // 从本地存储读取用户偏好 useEffect(() => { const storedPreference = localStorage.getItem('prefersLightMode'); try { if (storedPreference) { setLightMode(JSON.parse(storedPreference)); } else { const prefersLightMode = window.matchMedia('(prefers-color-scheme: light)').matches; setLightMode(prefersLightMode); } } catch (error) { console.log(error); } }, []); // 更新本地存储和body类名 useEffect(() => { try { localStorage.setItem('prefersLightMode', JSON.stringify(lightMode)); lightMode ? document.body.classList.add('light') : document.body.classList.remove('light'); } catch (error) { console.log(error); } }, [lightMode]); // 封装切换方法(也可直接暴露setLightMode,按需选择) const toggleLightMode = () => setLightMode(prev => !prev); return ( <ThemeContext.Provider value={{ lightMode, toggleLightMode, setLightMode }}> {children} </ThemeContext.Provider> ); } // 自定义Hook,简化组件调用 export function useTheme() { return useContext(ThemeContext); }
2. 在根组件中包裹Provider
确保整个应用能访问到ThemeContext的状态:
// src/App.jsx import { ThemeProvider } from './contexts/ThemeContext'; import ToggleComponent from './components/ToggleComponent'; function App() { return ( <ThemeProvider> {/* 其他业务组件 */} <ToggleComponent /> </ThemeProvider> ); } export default App;
3. 修改开关组件,通过Context获取状态和方法
替换原来直接使用的lightMode和setLightMode,改用Context提供的属性:
// src/components/ToggleComponent.jsx import { useTheme } from '../contexts/ThemeContext'; function ToggleComponent() { const { lightMode, toggleLightMode } = useTheme(); return ( <div className="form-control"> <label className="label cursor-pointer"> <span className="label-text">明暗模式切换</span> <input type="checkbox" className="toggle toggle-primary" checked={lightMode} // 绑定checked属性,确保UI与状态同步 onChange={toggleLightMode} /> </label> </div> ); } export default ToggleComponent;
错误原因分析
出现'setLightMode is not a function'的常见情况:
- 组件未被
ThemeProvider包裹,导致useContext获取到默认空值 - Context的
value对象中未正确包含setLightMode方法 - 解构时出现大小写错误,比如写成
setlightMode
内容的提问来源于stack exchange,提问作者trevinshu
相关产品推荐
相关产品推荐

