I’m using React Context to manage state in my application and I’m also using LocalStorage to persist some data between page refreshes. However, I’m running into an issue where the data stored in LocalStorage is not being maintained after a page refresh.
here is my code :
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 };
I’ve also tried to remove the useEffect where im getting the cart and mantain the one where i save in the localStorage my products but after refreshing it’s still gone.
2
Answers
Use state initializer function
I think there is an issue with the below code block
Each time page is refreshed the products are set to default which is a blank array. so a length check can be added as below which can solve your issue.
Example
Hope this will help. I have checked this locally and its working fine