Reputation: 621
I have a simple dropdown. I'ts refresh the state from localstorage and context. The context refresh and I can use everywhere in the page except in the select value.
This dropdown have an default value. (HU,EN,,DE,HR) It's not refresh although the state refresh
I'ts stay 'HU'. Although the state changed. The page other parts work properly
I use hooks. Thank you
Here is my codesandbox:
https://codesandbox.io/s/eager-river-t45b3r?file=/src/LanguageDropDown.js
LanguageDropDown.js
import React, { useState, useContext } from "react";
import GlobalContext from "./GlobalContext";
import classes from "./LanguageDropDown.module.css";
export default function LanguageDropDown() {
const { language, setLanguage } = useContext(GlobalContext);
console.log(`This is the language state from context: ${language}`);
return (
<div className={classes.div}>
<select
className={classes.languageDropDown}
value={language}
onChange={(e) => {
const selectedLanguage = e.target.value;
console.log(`this is the selected: ${selectedLanguage}`);
setLanguage(selectedLanguage);
localStorage.setItem("language", JSON.stringify(selectedLanguage));
}}
>
<option value="hu">HU</option>
<option value="en">EN</option>
<option value="de">DE</option>
<option value="hr">HR</option>
</select>
<h1>Here the good result:{language}</h1>
</div>
);
}
ContextWrapper.js
import React, { useState, useEffect } from "react";
import GlobalContext from "./GlobalContext";
export default function ContextWrapper(props) {
const [language, setLanguage] = useState("");
useEffect(() => {
const storageLanguage = localStorage.getItem("language");
console.log(`this is the storagelanguage: ${storageLanguage}`);
if (storageLanguage) {
function setLanguageData() {
setLanguage(storageLanguage);
}
setLanguageData();
}
}, [language]);
return (
<GlobalContext.Provider
value={{
language,
setLanguage,
}}
>
{props.children}
</GlobalContext.Provider>
);
}
Upvotes: 2
Views: 115
Reputation: 1
The answer provided above did not seem to resolve the issue to me (verified by going to the provided code sandbox and it still not working after making that change).
The issue is in the way that you are saving and parsing the value. You are JSON.stringify
ing the value when storing it, but you are not JSON.parse
ing it when retrieving it from localStorage. See this code sandbox for a solution: https://codesandbox.io/s/recursing-tree-7sn98k?file=/src/ContextWrapper.js
Alternatively, you could also not JSON.stringify
the value when storing it, but considering that localStorage values must be strings (or will be .toString()
'd otherwise) I do believe that the approach of stringifying the values on the way in is more fault-tolerant.
Upvotes: 0
Reputation: 1240
Try updating your useEffect to following:
useEffect(() => {
const storageLanguage = localStorage.getItem("language");
console.log(`this is the storagelanguage: ${storageLanguage}`);
if (storageLanguage) {
function setLanguageData() {
setLanguage(storageLanguage);
}
setLanguageData();
}
}, []); //Remove the language from here.
Adding [language]
to the dependency array executes the useEffect
each time language changes in the dropdown. This inturn set the value of the dropdown again.
Keep the dependency array empty in useEffect
, lets useEffect
execute only once, that solves the issue.
Upvotes: 1