Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can i save choosen theme in LocalStorage with React Context?

I want to create dark light mode using context. Everything is normal, I just can’t save to local storage. When you switch to dark mode and refresh, dark mode, but when you switch to light mode and refresh, it returns to dark mode. How can I solve this problem? The function works normally, the only problem was related to local, which when switching to light mode, dark mode is visible again .

import { createContext, useEffect, useState } from "react";


export const ThemeContext = createContext()

export const ThemeContextProvider = ({ children }) => {

    const [darkMode, setDarkMode] = useState(localStorage.getItem('Mode') ? localStorage.getItem('Mode') : false)

    const changeTheme = () => {
        setDarkMode(!darkMode)
    }

    useEffect(() => {
        localStorage.setItem('Mode', darkMode)
    }, [darkMode])

    return (
        <ThemeContext.Provider value={{ darkMode, changeTheme }}>
            {children}
        </ThemeContext.Provider>
    )
}

import React, { useContext } from 'react'
import { NavLink } from 'react-router-dom'
import { ThemeContext } from '../context/ThemeContext'
import { BiMoon } from "react-icons/bi"
import { BsSun } from "react-icons/bs"
const Header = () => {
    const { darkMode, changeTheme } = useContext(ThemeContext)
    return (
        <>
            <nav className="navbar navbar-expand-lg bg-dark navbar-dark">
                <div className="container-fluid">
                    <a className="navbar-brand" href="#">Navbar</a>
                    <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                        <span className="navbar-toggler-icon" />
                    </button>
                    <div className="collapse navbar-collapse" id="navbarNav">
                        <ul className="navbar-nav">
                            <li className="nav-item">
                                <NavLink className="nav-link active" to='/'>Home</NavLink>
                            </li>
                            <li className="nav-item">
                                <NavLink className="nav-link" to='/about'>About</NavLink>
                            </li>
                            <li className="nav-item">
                                <button onClick={changeTheme}>
                                    {darkMode ? <BsSun /> : <BiMoon />}
                                    changeTheme
                                </button>
                            </li>
                        </ul>
                    </div>
                </div>
            </nav>
        </>
    )
}

export default Header


import React from 'react'
import { BrowserRouter, Route, Routes } from 'react-router-dom'
import Home from "../pages/Home"
import About from "../pages/About"
import Header from '../components/Header'
import { ContextProvider } from "../context/GlobalState"
import { useContext } from 'react'
import { ThemeContext } from '../context/ThemeContext'
const AppRouter = () => {
    const { darkMode } = useContext(ThemeContext)
    return (
        <>
            <main className={darkMode ? 'dark' : 'light'}>
                <ContextProvider>
                    <BrowserRouter>
                        <Header />
                        <Routes>
                            <Route path='/' element={<Home />} />
                            <Route path='/about' element={<About />} />
                        </Routes>
                    </BrowserRouter>
                </ContextProvider>
            </main>


        </>
    )
}

export default AppRouter

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

The function localStorage.get always returns a string. Strings are always truthy. Consider this example:

localStorage.setItem("test", false);
if (localStorage.getItem("test")) {
    console.log("This always prints since the string \"false\" is considered truthy");
}

To fix your issue imply use JSON.parse:

const [darkMode, setDarkMode] = useState(localStorage.getItem('Mode') ? JSON.parse(localStorage.getItem('Mode')) : false)

Complete example, including getting rid of the useless use effect:

// Use the ?? operator to make it a bit shorter
const [darkMode, setDarkMode] = useState(
    JSON.parse(localStorage.getItem("mode")??"false")
);

// pass a callback to `setDarkMode` to avoid race conditions
const changeTheme = () => setDarkMode(darkMode=>{
        localStorage.setItem("Mode", !darkMode);
        return !darkMode;
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading