You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 01:38:41