I am trying to create dark/light mode toggle, however It doesn't seem to work when I refresh the page, it keeps being set to false, even though I change the theme. Why is it not remembering the true setting?
import * as React from 'react';
import './style.css';
import { useEffect, useState } from 'react';
export default function App() {
const [darkMode, setDarkMode] = useState(false);
function setTheme() {
const dark = JSON.parse(localStorage.getItem('darkMode'));
setDarkMode(dark);
console.log(darkMode);
}
useEffect(setTheme);
useEffect(() => {
if (darkMode == true) {
localStorage.setItem('darkMode', JSON.stringify(true));
document.body.style.background = 'red';
setDarkMode(true);
} else {
console.log(darkMode);
localStorage.setItem('darkMode', JSON.stringify(false));
document.body.style.background = 'black';
setDarkMode(false);
}
}, [darkMode]);
return (
<div>
<h1>Hello StackBlitz!</h1>
<button onClick={() => setDarkMode(true)}>set to true</button>
<button onClick={() => setDarkMode(false)}>set to false</button>
<p>Start editing to see some magic happen :)</p>
</div>
);
}
CodePudding user response:
There are a couple of things:
- Use any existing value for the initial state - make sure it's a boolean.
- You are checking the value of local storage, whereas you really want to check the
darkMode
state value. - You don't need to update the state inside the effect
// #1 use any existing value for the initial state
const initialState = localStorage.getItem("darkMode") === "true";
const [ darkMode, setDarkMode ] = useState(initialState);
useEffect(() => {
// #2 check the state value here
if (darkMode === true) {
localStorage.setItem("darkMode", JSON.stringify(true))
document.body.style.background = 'red'
// #3 don't update state
console.log('true!')
} else {
localStorage.setItem("darkMode", JSON.stringify(false))
document.body.style.background = 'black'
// #3 don't update state
console.log('false')
}
}, [darkMode])
Here's a playground: https://playcode.io/1008374