ð Issue
I created a Custom Hook to switch themes, but I’m facing this problem and I don’t exactly what could it be.
Basically, when I try to change the theme, it works perfectly. But, after refreshing the page, it doesn’t stay with the correct one and gives me this error.
⚙️ Reproduce the issue
You can reproduce this issue, cloning the Edite GitHub repository and follow the guide to set up the services.
ð» Code
Note: see that src is the root
hooks/useThemeSwitcher.js
import { useState, useEffect } from 'react'; function useThemeSwitcher(key, initialTheme) { const [theme, setTheme] = useState( () => { let storagedTheme = localStorage.getItem(key); storagedTheme = JSON.parse(storagedTheme) || initialTheme; } ); useEffect(() => { localStorage.setItem(key, JSON.stringify(theme)); }, [key, theme]); return [theme, setTheme]; } export default useThemeSwitcher;
App.js
function App() { // Current theme state (light/dark); const [theme, setTheme] = useThemeSwitcher('theme', dark); const toggleTheme = () => { setTheme(theme.title === 'dark' ? light : dark) } return ( <ThemeProvider theme={theme}> <Global /> {/* ...components */} <ToolbarLeft toggleTheme={toggleTheme} /> </ThemeProvider> ); }
components/Switch/index.js
// Components (styles) import { CustomSwitch } from './switch.styles'; function Switch({ isToggled, onSwitch }) { return ( <CustomSwitch> <input type="checkbox" checked={isToggled} onChange={onSwitch} /> <span /> </CustomSwitch> ) } export default Switch;
components/Toolbar/Left/index.js
// Components (styles) import { LeftContainer } from '../toolbar.styles'; // Components (children) import ToolsList from './tools'; function ToolbarLeft({ toggleTheme }) { return ( <LeftContainer> <ul> <ToolsList toggleTheme={toggleTheme} /> </ul> </LeftContainer> ) } export default ToolbarLeft;
components/Toolbar/Left/tools.js
function ToolsList({ toggleTheme }) { // Access and set the theme colors const { title } = useContext(ThemeContext); return ( <> {/* ...components */} {/* Theme switcher */} <Switch isToggled={title === 'dark'} onSwitch={toggleTheme} </Switch> </> ) }
Answer
The problem is that you are not returning storagedTheme
inside your useThemeSwitcher
hook.
So you could change your useThemeSwitcher.js
to something like this:
import { useState, useEffect } from "react"; function useThemeSwitcher(key, initialTheme) { const [theme, setTheme] = useState(() => { let storagedTheme = localStorage.getItem(key); return JSON.parse(storagedTheme) || initialTheme; }); useEffect(() => { localStorage.setItem(key, JSON.stringify(theme)); }, [key, theme]); return [theme, setTheme]; } export default useThemeSwitcher;