Reputation: 63
How to change state when localStorage
value changed. For example, I have a language switching button, like French and English, when I click English, it will be storing to localStorage
, when I click English it will also.
When I click the French the whole project need to see in French, also when I click English, want to do like that, it So how can I change state when I update localStorage
?
<button onclick={()=>localStorage.setItem("language",'english')}>English</button>
<button onclick={()=>localStorage.setItem("language",'french')}>French</button>
let language;
if (typeof window !== "undefined") {
if (localStorage.getItem("language") === null) {
language = "english";
}
if (localStorage.getItem("language") !== null) {
language = localStorage.getItem("language");
}
}
const [langu, setLangua] = useState(language);
console.log(langu);
Upvotes: 4
Views: 4710
Reputation: 46291
One way to achieve this that wouldn't change that much your current structure is first to change your buttons to this:
<button
onClick={() => {
localStorage.setItem("language", "english");
window.dispatchEvent(new Event("storage"));
}}
>
English
</button>
<button
onClick={() => {
localStorage.setItem("language", "french");
window.dispatchEvent(new Event("storage"));
}}
>
French
</button>
And then set up inside the component where you have setLangua
and langu
an useEffect
that would listen to changes in the localStorage
and update the state:
useEffect(() => {
const listenStorageChange = () => {
if (localStorage.getItem("language") === null) {
setLangua("english");
} else {
setLangua(localStorage.getItem("language"));
}
};
window.addEventListener("storage", listenStorageChange);
return () => window.removeEventListener("storage", listenStorageChange);
}, []);
Upvotes: 9
Reputation: 396
You can setLangua at the same time as putting it in local storage. Or you can subscribe to local storage changes with the useEffect hook.
import { useCallback, useEffect, useState } from 'react'
const [userLang, setUserLang] = useState('english')
const getLangFromLocalStorage = useCallback(() => {
return localStorage.getItem('userLang');
}, []);
useEffect(() => {
function checkUserLang() {
const value = getLangFromLocalStorage()
// Do with value what you want
if (value) {
setUserLang(value)
}
}
window.addEventListener('storage', checkUserLang)
return () => {
window.removeEventListener('storage', checkUserLang)
}
}, [])
// Set userLang initially when component did mount
useEffect(() => {
const value = getLangFromLocalStorage();
if (value) {
setUserLang(value);
}
}, []);
Note: This won't work on the same page that is making the changes — it is really a way for other pages on the domain using the storage to sync any changes that are made. Pages on other domains can't access the same storage objects.
Upvotes: 0
Reputation: 17594
you need set it in useEffect
hook, with empty dependences, it will run only when the component mount.
const [langu,setLangua] = useState(language)
useEffect(() => {
let language = ""
if (typeof window !== 'undefined') {
if ( localStorage.getItem("language") === null) {
language = "english"
}
if ( localStorage.getItem("language") !== null) {
language = localStorage.getItem("language")
}
}
setLanguage(language)
}, [])
Upvotes: 0