In Next.js I’m using this code:
const [card, setcard] = useState([]);
useEffect(() => {
localStorage.setItem('items', JSON.stringify(card));
}, [card]);
useEffect(() => {
const items = JSON.parse(localStorage.getItem('items'));
if (items) {
setcard(items);
}
}, []);
I can see that when the value of the card changes, the local storage shows me the value of the card, which is a JSON, so when I refresh, I just see this []
I used this tutorial: https://www.freecodecamp.org/news/how-to-use-localstorage-with-react-hooks-to-set-and-get-items/
How can I fix the code so I don’t lose the value of the card after a refresh?
Also, I was using cookies
to store the card
like this, and it was working, but when the items in my JSON got larger, the cookie didn’t store anymore; that’s why I want to use local storage.
Example:
const [card, setcard] = useState(() => eval(getCookie('card') || []));
setCookie('card', JSON.stringify(card), {
path: '/',
maxAge: 60 * 60 * 24,
HttpOnly: true,
Secure: true,
});
3
Answers
When your page reloads, the cards are set to
[]
and theuseEffect
hook gets called so local storage’sitems
is set to[]
.You need to check whether card has length or not and then set.
The issue is that your first
useEffect
(with the dependency array[card]
) gets triggered before youruseEffect
hook without any dependency array. You could probably fix it by reversing the order of them, but I would be more thorough than that and only have the one with the[card]
dependency array do the save if it sees something other than the default[]
that you’re supplying. Here’s a way to do that:Using object identity makes it so that the code will never save the specific empty array we used as a default (but will store an empty array resulting from the user removing all the cards on purpose).
Alternatively, don’t rely on an effect to save the array. Instead, have a wrapper for
setCard
:(I’ve used
setCard
rather thansetcard
in these because the vastly common standard is to capitalize the noun afterset
in these things rather than use all lower-case.The main issue is that your initial
card
value is[]
, regardless of the contents ofitems
inlocalStorage
.Instead of using
[]
, you should first checklocalStorage
. If there there is no value foritems
, use your default[]
. However if there is a value present, use that as initial value instead.