Description
I am creating a dark/light mode feature using context in useContext in React.JS, but I am encountering a problem. I am new to using useContext in react.js, so I am asking for help to find the problem.
Problem
When i set theme, it returns error.
Code
ModeProvider.js
import React, { useState } from "react"
export const ModeContext = React.createContext([])
const ModeProvider = ({ children }) => {
const [darkMode, setDarkMode] = useState(true)
return (
<ModeContext.Provider value={[darkMode, setDarkMode]}>
{children}
</ModeContext.Provider>
)
}
export default ModeProvider
ModeButton.js (as component)
import React from "react"
import DayIcon from "images/daymode.svg"
import NightIcon from "images/nightmode.svg"
import { ImgButton } from "./ModeButton.styles"
const ModeButton = ({ darkMode, setDarkMode }) => (
<ImgButton
src={darkMode ? NightIcon : DayIcon}
alt="mode"
onClick={() => setDarkMode(prevState => !prevState)}
/>
)
export default ModeButton
Header.js
import React, { useState, useContext } from 'react'
import { Link } from 'gatsby'
import useConfigQuery from '../../hooks/useConfigQuery'
import { Wrapper, Logo } from './Header.styles'
import Menu from 'components/Menu'
import Hamburger from 'components/Hamburger'
import MobileMenu from 'components/MobileMenu'
import ModeButton from "components/ModeButton"
import { ModeContext } from '../../context/ModeProvider'
const Header = ({ siteTitle = "" }) => {
const [darkMode, setDarkMode] = useContext(ModeContext);
const [menuOpen, setMenuOpen] = useState(false);
const siteConfig = useConfigQuery()
return (
<Wrapper>
<Hamburger menuOpen={menuOpen} setMenuOpen={setMenuOpen}/>
<MobileMenu menuOpen={menuOpen} items={siteConfig.menu}/>
<Menu items={siteConfig.menu}/>
<Link to="/">
<Logo src={siteConfig.logo.publicURL} alt={siteTitle}/>
</Link>
<ModeButton darkMode={darkMode} setDarkMode={setDarkMode} />
</Wrapper>
)
}
export default Header;
Layout.js
import Header from 'components/Header'
import { ModeContext } from 'context/ModeProvider'
const Layout = ({ children }) => {
const [darkMode] = useContext(ModeContext);
const data = useMetaDataQuery();
console.log(data)
return (
<ThemeProvider theme={darkMode ? darkTheme : lightTheme}>
<GlobalStyles/>
<Header siteTitle={data.title}/>
{children}
</ThemeProvider>
)
}
Question
How to fix the update state code so the error can be resolved ?
Any help will be appreciated, thank you
>Solution :
You don’t appear to be providing a ModeContext.Provider – you don’t include it in the component hierarchy (or, if you do you’re not showing that bit of the code).
It will need to be in another component that encloses all components where you’re calling useContext(ModeContext), e.g.
import Header from 'components/Header'
import ModeProvider, { ModeContext } from 'context/ModeProvider'
const Layout = ({ children }) => (
<ModeProvider>
<InnerLayout>{children}</InnerLayout>
</ModeProvider>
);
const InnerLayout = ({ children }) => {
const [darkMode] = useContext(ModeContext);
const data = useMetaDataQuery();
console.log(data)
return (
<ThemeProvider theme={darkMode ? darkTheme : lightTheme}>
<GlobalStyles/>
<Header siteTitle={data.title}/>
{children}
</ThemeProvider>
)
}
