I have a state that stores the current app's theme either dark or light. I use useEffect hook to store the state changes in localStorage so that when the user refreshes the page, their preferred theme will get saved and another useEffect hook to update my state during the initial load. However, my state does not update during that initial load.
Things I've tried:
- Make sure the useEffect during initial load is placed before the useEffect to store the theme state
- Use Promise to make sure that my changeTheme function is only triggered after the state has changed on load
- I logged my results so I know that localStorage did not have any problems with saving my states or keeping track the changes, but the setState function inside my first useEffect hook was the one that did not update my state properly.
Below are my codes:
const [theme, setTheme] = useState({});
useEffect(() => {
const loadedTheme = JSON.parse(localStorage.getItem(themeStorage))
if (loadedTheme) {
console.log("Initial load")
console.log(loadedTheme);
console.log("Setting theme to localStorage")
Promise.resolve()
.then(() => { setTheme({ dark: loadedTheme.dark }) })
.then(() => { console.log(theme) })
.then(() => changeTheme())
}
}, [])
useEffect(() => {
localStorage.setItem(themeStorage, JSON.stringify(theme))
console.log("Inside useEffect to save changed theme")
console.log(theme)
}, [theme])
function changeTheme() {
console.log("Inside changeTheme function");
console.log(theme);
if (!theme || !theme.dark) { //light turns to dark
for (let vars of Object.keys(varTheme)) {
document.documentElement.style.setProperty(`--${vars}`, varTheme[vars][0]);
}
setTheme({ ...theme, dark: true })
}
else {
for (let vars of Object.keys(varTheme)) { //dark turns to light
document.documentElement.style.setProperty(`--${vars}`, varTheme[vars][1]);
}
setTheme({ ...theme, dark: false })
}
}