Search code examples
javascriptreactjsstyled-componentsreact-context

Context API with Styled Components Error: setTheme is not a function


I am using context API for the first time and trying to implement dark mode in an application using styled components. When trying to toggle the theme, I get the error 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;

In the context file I have this:

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>
  );
};

 

And in the component where I'm attempting to theme switch, I have this:

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;


Solution

  • Your ThemeContext import is wrong in the component where you are attempting this.Rather than importing from 'styled-components' import it from your context provider file.

    import { ThemeContext } from 'path of your theme context provider'