javascript 为什么刷新时本地存储会被删除?

kxe2p93d  于 2023-03-28  发布在  Java
关注(0)|答案(3)|浏览(159)

在Next.js中,我使用以下代码:

const [card, setcard] = useState([]);

  useEffect(() => {
    localStorage.setItem('items', JSON.stringify(card));
  }, [card]);

  useEffect(() => {
    const items = JSON.parse(localStorage.getItem('items'));
    if (items) {
      setcard(items);
    }
  }, []);

我可以看到,当卡片的值更改时,本地存储会显示卡片的值,这是一个JSON,因此当我刷新时,我只看到这个[]
我使用了这个教程:https://www.freecodecamp.org/news/how-to-use-localstorage-with-react-hooks-to-set-and-get-items/
如何修复代码,以便在刷新后不会丢失卡的值?
另外,我使用cookies来存储card,它是工作的,但是当我的JSON中的项目变大时,cookie不再存储;这就是为什么我想使用本地存储。
示例:

const [card, setcard] = useState(() => eval(getCookie('card') || []));
  setCookie('card', JSON.stringify(card), {
    path: '/',
    maxAge: 60 * 60 * 24,
    HttpOnly: true,
    Secure: true,
  });
5us2dqdw

5us2dqdw1#

问题是您的第一个useEffect(带有依赖数组[card])在没有任何依赖数组的情况下在useEffect钩子之前被触发。你可以通过颠倒它们的顺序来修复它,但我会更彻底,只有一个与[card]依赖关系数组做保存,如果它看到的东西以外的默认[],你'我们提供。这里有一个方法:

// Outside the component
const defaultCard = [];

function YourComponent() {
    const [card, setCard] = useState(defaultCard);

    useEffect(() => {
        const items = JSON.parse(localStorage.getItem("items"));
        if (items) {
            setCard(items);
        }
    }, []);

    useEffect(() => {
        if (card !== defaultCard) { // Note we're checking *object identity* here
            localStorage.setItem("items", JSON.stringify(card));
        }
    }, [card]);
    
    // ...
}

使用对象标识使得代码永远不会保存我们用作默认值的 * 特定 * 空数组(但是存储用户故意删除所有卡所产生的空数组)。
或者,不要依赖效果来保存数组。相反,为setCard创建一个 Package 器:

function YourComponent() {
    const [card, setCardWorker] = useState(defaultCard);

    const setCard = useCallback(
        (card) => {
            localStorage.setItem("items", JSON.stringify(card));
            setCardWorker(card);
        },
        [setCardWorker]
    );

    useEffect(() => {
        const items = JSON.parse(localStorage.getItem("items"));
        if (items) {
            setCard(items);
        }
    }, []);
    
    // ...code using `setCard` to update `card` as things are added and removed...
}
  • (我在这些文章中使用了setCard而不是setcard,因为在这些文章中,最常见的标准是将set后面的名词大写,而不是全部使用小写。
8gsdolmq

8gsdolmq2#

当页面重新加载时,卡被设置为[],并调用useEffect钩子,因此本地存储的items被设置为[]
您需要检查卡片是否有长度,然后进行设置。

const [card, setcard] = useState([]);

useEffect(() => {
  if (card.length) {
    localStorage.setItem('items', JSON.stringify(card));
  }
}, [card]);

useEffect(() => {
  const items = JSON.parse(localStorage.getItem('items'));
  if (items) {
    setcard(items);
  }
}, []);
brgchamk

brgchamk3#

主要的问题是,初始的card值是[],而不管localStorageitems的内容是什么。
不使用[],你应该先检查localStorage。如果items没有值,使用默认的[]。但是如果有一个值,使用它作为初始值。

const [card, setcard] = useState(() => {
  const json = localStorage.getItem('items');
  if (!json) return []; // default card
  return JSON.parse(json);
});

useEffect(() => {
  localStorage.setItem('items', JSON.stringify(card));
}, [card]);

相关问题