import { useEffect, useState } from 'react';
function useBookmarks() {
const [bookmarks, setBookmarks] = useState(() => {
const ls = localStorage.getItem('bookmarks');
if (ls) return JSON.parse(ls);
else return [];
});
const toggleItemInLocalStorage = (id) => () => {
const isBookmarked = bookmarks.includes(id);
if (isBookmarked) setBookmarks((prev) => prev.filter((b) => b !== id));
else setBookmarks((prev) => [...prev, id]);
};
useEffect(() => {
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
}, [bookmarks]);
return [bookmarks, toggleItemInLocalStorage];
}
export default useBookmarks;
Please tell me why the localStorage is not defined. when I use localStorage why always, ReferenceError: localStorage is not defined. is there something wrong with my code. Please help me
CodePudding user response:
You can add another conditional to check if the window object is defined, before calling localStorage:
if (typeof window !== 'undefined') {
const ls = localStorage.getItem('bookmarks');
}
CodePudding user response:
The standard localStorage API should be available in browsers. No need to specifically declare it.
But when you're rendering on the server, you do not have a browser and thus you do not have access to all the APIs that the browser provides, including localStorage.
In JavaScript code that is running both on the server and on the client (browser), it is common practice to guard against with an if clause that checks if window is defined. window
is the root object provided by the browser for all the APIs that are provided by the browser.
For example:
if (typeof window !== 'undefined') {
localStorage.setItem('myMouse', 'Jerry');
}
In your case, you may want to change your code to below:
import { useEffect, useState } from 'react';
function useBookmarks() {
const [bookmarks, setBookmarks] = useState(() => {
let ls;
if (typeof window !== 'undefined') {
ls = localStorage.getItem('bookmarks');
}
if (ls) return JSON.parse(ls);
else return [];
});
const toggleItemInLocalStorage = (id) => () => {
const isBookmarked = bookmarks.includes(id);
if (isBookmarked) setBookmarks((prev) => prev.filter((b) => b !== id));
else setBookmarks((prev) => [...prev, id]);
};
useEffect(() => {
if (typeof window !== 'undefined') {
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
}
}, [bookmarks]);
return [bookmarks, toggleItemInLocalStorage];
}
export default useBookmarks;
CodePudding user response:
I think the problem might be from initial value of bookmarks because you are setting function as value not localStorage value
change this :
const [bookmarks, setBookmarks] = useState(() => {
const ls = localStorage.getItem('bookmarks');
if (ls) return JSON.parse(ls);
else return [];
});
to this :
const ls = localStorage.getItem('bookmarks');
const [bookmarks, setBookmarks] = useState(ls ? JSON.parse(ls) : []);