'React: Mapping a component with local storage data
I'm currently creating a history list component for a form in a react app and am having some trouble with the local storage.
Essentially, I want the app to render a list of past inputs from the user's local storage data. My current idea is based in duplicating the local storage data is a state variable.
const [history, setHistory] = useState([]);
On form submit I call this function with the form input as the parameter (the input is a single string)
const setLocalStorage = (input) => {
const hist = JSON.parse(localStorage.getItem('history')) || [];
console.log(hist)
hist.push(input)
localStorage.setItem('history', JSON.stringify(hist))
setHistory(hist);
}
This is meant to put the history from local story into hist, push the input that was just submitted into the existing array hist, and update the local storage with the new value. The state variable should then be updated with the most updated array of strings with the setHistory(hist) call.
Also, I want local storage to be pulled on first render so I can use that data to render the history list on initial load. I have a useEffect hook for this as shown:
useEffect(() => {
setHistory(JSON.parse(localStorage.getItem('history')))
console.log(history)
}, []);
The problem I'm facing is that the state never seems to get updated? I can instead do a console log for JSON.parse(localStorage.getItem('history')) and get the local storage array returned but this of course isn't helpful for data usage. I know that the local storage is properly being pulled from this but I'm unable to update the state for some reason. I need the state updated so I can conditionally render and use the array for mapping each item on the history list. When I console log "history" I get an empty array.
TL;DR
Concisely, what is the cleanest method to have local storage and state values maintain equivalency? Hope my post was clear enough to understand!
I'm remaking and updating a regular JS app on React for practice so I'm able to provide a live link of how I want this simple component to work.
Solution 1:[1]
The second returned parameter of useState is similar to the this.setState which is asynchronous. You may see that state is not changed even setHistory is called. Passing function instead of the value will avoid this issue as it will be executed after the state is updated. This might be useful for better understanding Passing function to setState()
useEffect(() => {
const hist = JSON.parse(localStorage.getItem('history'))
setHistory(prevHistory => [...prevHistory, ...hist])
}, []);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | OrcunSelbasan |
