使用Context API+Styled Components实现暗黑模式报错:setTheme不是函数
解决React中Context API+Styled Components暗黑模式切换时
setTheme is not defined的报错 问题场景
首次尝试用Context API配合Styled Components实现React应用的暗黑模式切换,点击主题切换按钮时触发报错:setTheme is not defined。
相关代码
App.js
import { ThemeContext, ThemeProviderWrapper } from "./context/ThemeContext"; import { ThemeProvider } from "styled-components"; import { lightTheme, darkTheme } from "./theme"; import Home from "./pages/Home"; import GlobalStyles from "./styles/Global.styled"; import { Outlet } from "react-router-dom"; import { useContext } from "react"; const App = () => { const { theme } = useContext(ThemeContext); return ( <ThemeProviderWrapper> <ThemeProvider theme={theme === "light" ? lightTheme : darkTheme}> <Home /> <Outlet /> <GlobalStyles /> </ThemeProvider> </ThemeProviderWrapper> ); }; export default App;
上下文文件(./context/ThemeContext.js)
import React, { useState, createContext } from "react"; export const ThemeContext = createContext({ theme: "light", setTheme: () => {}, }); export const ThemeProviderWrapper = ({ children }) => { const [theme, setTheme] = useState("light"); return ( <ThemeContext.Provider value={{ theme, setTheme }}> {children} </ThemeContext.Provider> ); };
Header组件(主题切换组件)
import { Navbar, StyledFontAwesomeIcon, ToggleSwitch, ToggleSwitchText, Title, } from "../styles/Navbar.styled"; import { faMoon } from "@fortawesome/free-regular-svg-icons"; import { useContext } from "react"; import { ThemeContext } from "styled-components"; const Header = () => { const { theme, setTheme } = useContext(ThemeContext); const handleClick = () => { setTheme(theme === "light" ? "dark" : "light"); }; return ( <Navbar> <Title>Where in the world?</Title> <ToggleSwitch onClick={handleClick}> <StyledFontAwesomeIcon icon={faMoon} /> <ToggleSwitchText>Dark Mode</ToggleSwitchText> </ToggleSwitch> </Navbar> ); }; export default Header;
错误原因
Header组件里的ThemeContext是从styled-components库导入的,而非我们自己在./context/ThemeContext中定义的上下文。Styled Components自带的ThemeContext仅提供主题样式数据,不包含我们自定义的setTheme方法,所以调用时会提示该方法未定义。
修复步骤
修改Header组件的导入语句,将ThemeContext的来源替换为自定义的上下文文件:
// 替换原导入语句 import { ThemeContext } from "../context/ThemeContext";
修复后的Header组件代码
import { Navbar, StyledFontAwesomeIcon, ToggleSwitch, ToggleSwitchText, Title, } from "../styles/Navbar.styled"; import { faMoon } from "@fortawesome/free-regular-svg-icons"; import { useContext } from "react"; import { ThemeContext } from "../context/ThemeContext"; // 修正导入路径 const Header = () => { const { theme, setTheme } = useContext(ThemeContext); const handleClick = () => { setTheme(theme === "light" ? "dark" : "light"); }; return ( <Navbar> <Title>Where in the world?</Title> <ToggleSwitch onClick={handleClick}> <StyledFontAwesomeIcon icon={faMoon} /> <ToggleSwitchText>Dark Mode</ToggleSwitchText> </ToggleSwitch> </Navbar> ); }; export default Header;
这样就能正确获取到包含setTheme方法的自定义上下文,主题切换功能即可正常工作。
内容的提问来源于stack exchange,提问作者Ope Afolabi
相关产品推荐
相关产品推荐

