๐ 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> </> ) }
Advertisement
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;