React中如何从其他组件修改React Context的值实现主题切换
核心实现逻辑
你需要在 ThemeProvider 内部维护主题状态,同时将「当前主题值」和「修改主题的方法」一起通过 Context 暴露给下游组件,下游的切换组件直接调用暴露的方法即可触发全局主题更新。
各文件修改代码
1. ThemeProvider.jsx
import React, {createContext, useState} from "react"; import {THEME_TYPE} from "../constants"; // 调整 Context 默认值结构,包含主题值和修改方法占位 export const ThemeContext = createContext({ theme: THEME_TYPE.LIGHT, setTheme: () => {} }); const ThemeProvider = ({ children }) => { // 内部维护主题状态 const [theme, setTheme] = useState(THEME_TYPE.LIGHT); return ( <ThemeContext.Provider value={{ theme, setTheme }}> {children} </ThemeContext.Provider> ); }; export default ThemeProvider;
2. ThemeSwitcher.jsx
import React, {useContext} from "react"; import { THEME_TYPE } from "../constants"; import {ThemeContext} from "../providers/ThemeProvider"; const ThemeSwitcher = () => { // 解构出主题值和修改方法 const { theme: themeMode, setTheme } = useContext(ThemeContext); const handleThemeChange = (e) => { // 根据 checkbox 选中状态切换主题 const newTheme = e.target.checked ? THEME_TYPE.DARK : THEME_TYPE.LIGHT; setTheme(newTheme); }; return ( <div className="switch-container"> <label className="switch"> <input data-testid="theme-changer" type="checkbox" checked={themeMode === THEME_TYPE.DARK} onChange={handleThemeChange} /> <span className="slider round"></span> </label> <span className="text-color bold">Dark mode</span> </div> ); }; export default ThemeSwitcher;
3. App.jsx(仅需修改 StyleTag 内部的 Context 消费逻辑)
import React, {useContext} from "react"; import { Helmet } from "react-helmet"; import NameBox from "./components/NameBox"; import ThemeSwitcher from "./components/ThemeSwitcher"; import { THEME_TYPE } from "./constants"; import Styles from "./data/Styles"; import ThemeProvider from "./providers/ThemeProvider"; import {ThemeContext} from "./providers/ThemeProvider"; const StyleTag = () => { // 解构出主题值 const { theme: themeMode } = useContext(ThemeContext); return ( <Helmet> <style>{Styles(themeMode)}</style> </Helmet> ); }; function App() { return ( <ThemeProvider> <StyleTag /> <NameBox /> <ThemeSwitcher /> </ThemeProvider> ); } export default App;
补充说明
styles.js 文件无需任何修改,原有逻辑可正常适配新的主题切换逻辑。
内容的提问来源于stack exchange,提问作者ali varaste pour
相关产品推荐
相关产品推荐

