next.js LocalStorage with React Context not persisting data on refresh [duplicate]

pftdvrlh  于 2023-05-17  发布在  React
关注(0)|答案(2)|浏览(188)

此问题已在此处有答案

How to set the state based on the local storage without overwriting it with the initial state?(1个答案)
7天前关闭
我使用React Context来管理应用程序中的状态,我还使用LocalStorage在页面刷新之间持久化一些数据。然而,我遇到了一个问题,即在页面刷新后,存储在LocalStorage中的数据没有得到维护。下面是我的代码:

import { Product } from "@prisma/client";
import { ReactNode, createContext, useEffect, useState } from "react";

interface CartProduct extends Product {
  quantity: number;
}

interface Products {
  products: CartProduct[];
  addProduct: (product: Product) => void;
  removeProduct: (product: Product) => void;
}

const CartContext = createContext<Products>({
  products: [],
  addProduct: () => {},
  removeProduct: () => {},
});

function CartProvider({ children }: { children: ReactNode }) {
  const [products, setProducts] = useState<CartProduct[]>([]);

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

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

  function addProduct(product: Product) {
    const existingProduct = products.find((p) => p.id === product.id);

    if (existingProduct) {
      const updatedProducts = products.map((p) => {
        if (p.id === product.id) {
          return { ...p, quantity: p.quantity + 1 };
        } else {
          return p;
        }
      });

      setProducts(updatedProducts);
    } else {
      const newProduct = { ...product, quantity: 1 } as CartProduct;
      const updatedProducts = [...products, newProduct];

      setProducts(updatedProducts);
    }
  }

  function removeProduct(product: Product) {
    const existingProduct = products.find((p) => p.id === product.id);
    if (existingProduct && existingProduct.quantity > 1) {
      const updatedProducts = products.map((p) => {
        if (p.id === product.id) {
          return { ...p, quantity: p.quantity - 1 };
        } else {
          return p;
        }
      });
      setProducts(updatedProducts);
    } else {
      const updatedProducts = products.filter((p) => p.id !== product.id);
      setProducts(updatedProducts);
    }
  }

  const cartContextValue = { products, addProduct, removeProduct };

  return (
    <CartContext.Provider value={cartContextValue}>
      {children}
    </CartContext.Provider>
  );
}

export { CartContext, CartProvider };

我也试图删除useEffect,其中我得到的车和维护的一个地方,我保存在本地存储我的产品,但刷新后,它仍然消失了。

yshpjwxd

yshpjwxd1#

使用状态初始化函数

const [products, setProducts] = useState<CartProduct[]>(() => {
  const cart = localStorage.getItem("cart")
  return cart ? JSON.parse(card) : []
});

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

sqyvllje2#

我认为下面的代码块有问题

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

每次刷新页面时,产品都设置为默认值,即空白数组。因此,可以添加如下长度检查,这可以解决您的问题。
示例

useEffect(() => {
      if(products.length > 0){
            localStorage.setItem("cart", JSON.stringify(products));
      }
    }, [products]);

希望这会有所帮助。我在当地检查过了,它工作正常

相关问题