【问题标题】:Why my localStorage gets empty each time i reload the page?为什么每次我重新加载页面时我的 localStorage 都会变空?
【发布时间】:2021-04-18 03:24:52
【问题描述】:

我不明白该怎么做。我以为只是 .setItem 和 .getItem 但可能 useState 更改状态有问题

 const LOCAL_STORAGE_KEY = "products";
  const [products, setProducts] = useState([]);

  const addProductHandler = (product) => {
    console.log(product);
    setProducts([...products, { id: uuid(), ...product }]);
  };


  useEffect(() => {
    localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(products));
  }, [products]);

  useEffect(() => {
    const retriveProducts = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY));
    if (retriveProducts) setProducts(retriveProducts);
  }, []);

【问题讨论】:

  • 现在您在每次安装组件时使用默认的空数组设置它。如果本地存储中不存在密钥,您只想这样做。
  • 我想,如果产品有任何变化,那么 setItems 的 useState 就会被调用。那么问题出在 getItems 的 useState 中吗?如果您能详细了解这里实际发生的情况
  • 您将 localStorage 设置为挂载时的空数组

标签: reactjs react-hooks local-storage


【解决方案1】:

当组件挂载时,您将products 的初始状态设置为一个空数组。然后你存储到localStorage:

useEffect(() => {
  localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(products));
}, [products]);

在你从本地存储恢复状态(你刚刚存储的空数组)之后,这意味着初始状态总是空的:

useEffect(() => {
  const retriveProducts = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY));
  if (retriveProducts) setProducts(retriveProducts);
}, []);

为了解决问题,改变useEffect块的顺序(先恢复再存储),防止存储useEffect设置一个空数组到本地存储:

useEffect(() => {
  const retriveProducts = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY));
  if (retriveProducts) setProducts(retriveProducts);
}, []);

useEffect(() => {
  if(products?.length) { // only store the state if products exists and it's length is greater than 0
    localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(products));
  }
}, [products]);

【讨论】:

  • 好的,所以在使用 useEffects 时顺序也很重要?我不知道这件事。不过,您的回答对我的问题有效。谢谢
  • 确实如此。顺序很重要。不客气:)
  • 这是新的optional chaining 语法。
  • 谢谢 Ori Drori
  • 太棒了。谢谢你。迄今为止最好的解释,解决了很多 m 个问题!
【解决方案2】:

继续评论

const LOCAL_STORAGE_KEY = "products";
const [products, setProducts] = useState([]);

const addProductHandler = (product) => {
  console.log(product);
  setProducts([...products, { id: uuid(), ...product }]);
  localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(products));
};

useEffect(() => {
  // Updating the state on mount if data exists in LC else state would be the default state
  if (localStorage.getItem(LOCAL_STORAGE_KEY)) {
    const retriveProducts = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY));
    if (retriveProducts) setProducts(retriveProducts);
  }
}, []);

【讨论】:

    猜你喜欢
    • 2014-06-20
    • 2019-10-22
    • 2019-05-16
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    • 2015-08-28
    相关资源
    最近更新 更多