I am using Context API
to pass my Cart data to different pages, and trying to use localStorage
to set and retrieve the Cart data while refreshing the page.
Setting the Cart data to localStorage
after every change of the state
is working fine, but the problem is that when the page is refreshed, the data of localStorage
is gone and so the Cart data will be reset!
I don’t understand where I’m doing something wrong and why localStorage
data won’t be set and used while page is refreshed. Can you please help me out with this? (For display purposes I’m just log
ging the localStorage
value for now.)
Here is my code:
function CartProvider({ children }: Props) {
const [state, dispatch] = useReducer(reducer, initialState);
const [retrievedState, setRetrievedState] = useState(
JSON.parse(localStorage.getItem("cart") || "") || initialState
);
useEffect(() => {
localStorage.setItem("cart", JSON.stringify(state));
setRetrievedState(state);
}, [state]);
console.log(retrievedState);
return (
<CartContext.Provider value={{ state, dispatch }}>
{children}
</CartContext.Provider>
);
}
2
Answers
So I found out that the solution for this issue is that we retrieve the
state
fromlocalStorage
when thecomponent
mount
s (won't be needingretrievedState
and it'ssetRetrievedState
anymore), and if a value is found, wedispatch
anaction
to hydrate thestate
with this value, and we updatelocalStorage
whenever thestate
changes, like so:And of course we should add a
'HYDRATE_STATE'
action
appropriately to set thestate
with thepayload
. Something like this:In context provider, when you refresh, all values are set to empty/ initial state.
In your code you are using useEffect, so on first render you are setting the localStorage to a value from state.
If state is not already defined, then its going to set localStorage to empty, and when you change the state, localStorage is set again.
You should be inspecting the
state
variable and make sure that it has some values when page refreshes. Other than that I don’t see any flaws in the code.