I’m trying to apply the theme the user chose to the initial value of useState(), but when I refresh the page, the choice does not apply. What do I have to change in order for the value to persist through page refreshing?
theme-toggler.js
import React, { createContext, useState } from "react"; export const themes = { light: { background: "#41A9EC", fontColor: '#FFF' }, dark: { background: "#F9F9", fontColor: '#000' } } export const ThemeContext = createContext({}) export const ThemeProvider = (props) => { const [theme, setTheme] = useState(localStorage.themes) if(theme === themes.light) { localStorage.setItem('themes', JSON.stringify(themes.light)) } if(theme === themes.dark) { localStorage.setItem('themes', JSON.stringify(themes.dark)) } return ( <ThemeContext.Provider value={{ theme, setTheme }}> {props.children} </ThemeContext.Provider> ) }
theme-toggler-button.js
import React, { useContext } from "react" import { ThemeContext, themes } from "../../context/theme-toggler" import { Button } from "../button/button" export const ThemeTogglerButton = () => { const { theme, setTheme } = useContext(ThemeContext) return ( <div style={{ backgroundColor: theme.background, color: theme.fontColor }}> <Button onClick={() => setTheme(theme === themes.light ? themes.dark : themes.light)}>Theme Toggler</Button> </div> ) }
Thanks in advance.
Advertisement
Answer
After a few days, I was able to make it work. I’m posting the solution I found, in order to help others with similar problems.
theme-toggler-button file:
import React, { useContext } from "react" import { ThemeContext, themes } from "../../context/theme-toggler" import { Button } from "../button" export const ThemeTogglerButton = () => { const { theme, setTheme } = useContext(ThemeContext) function handleClick() { const localTheme = JSON.parse(localStorage.getItem("themes")) console.log(localTheme) setTheme(theme === themes.light ? themes.dark : themes.light) if (localTheme) { localStorage.setItem('themes', JSON.stringify(localTheme.name === 'light mode' ? themes.dark : themes.light)) } else { localStorage.setItem('themes', JSON.stringify(themes.light)) } } return ( <Button style={{ backgroundColor: theme.background, color: theme.fontColor }} onClick={() => handleClick()}>{ (theme === themes.light ? themes.dark.name : themes.light.name)} </Button> ) }
theme-toggler file:
import React, { createContext, useState, useEffect } from "react"; export const themes = { light: { name: 'light mode', background: '#41A9EC', fontColor: '#FFF' }, dark: { name: 'dark mode', background: '#212121', fontColor: '#AAB0BC' } } export const ThemeContext = createContext({}) export const ThemeProvider = (props) => { const [theme, setTheme] = useState([]) useEffect(() => { const localTheme = JSON.parse(localStorage.getItem("themes")) if (!localTheme) { localStorage.setItem('themes', JSON.stringify(themes.light)) setTheme(themes.light) } if (localTheme) { if (localTheme.name === 'light mode') { localStorage.setItem('themes', JSON.stringify(themes.light)) setTheme(themes.light) } if (localTheme.name === 'dark mode') { localStorage.setItem('themes', JSON.stringify(themes.dark)) setTheme(themes.dark) } } }, []) return ( <ThemeContext.Provider value={{ theme, setTheme }}> {props.children} </ThemeContext.Provider> ) }
Please find below my project repository, where I’m currently using the solution above: https://github.com/Alex-Lima84/pokemon-react-api