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.
You can reproduce this issue, cloning the Edite GitHub repository and follow the guide to set up the services.
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>
</>
)
}
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;