Skip to content
Advertisement

Theme toggler React – Choice not persisting through page refreshing

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

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement