React在线商店- createContext在页面重新加载时不保留数据

dwthyt8l  于 2023-01-02  发布在  React
关注(0)|答案(1)|浏览(201)

在学习React的过程中,我决定尝试创建自己的在线商店。就在学习和实现createContext功能和处理之后,我遇到了它在页面刷新/重新加载时不能保存数据的问题。
最简单的解决方案可能是将数据存储到localStorage中,但我不知道如何将localStorage项作为整个createContext(contextValue)数组来实现和处理,并在每个上下文的函数更改时保持更新。
在React中有什么简单的解决方案吗?或者在react中处理这样的上下文的最好的JS解决方案是什么?

import { createContext, useState } from "react";
import { productsArray, getProductData } from "./productsConfig";

export const CartContext = createContext({
    items: [],
    getProductQuantity: () => {},
    addOneToCart:       () => {},
    removeOneFromCart:  () => {},
    deleteFromCart:     () => {},
    getTotalCost:       () => {}
});

export function CartProvider({children}) {
    const [cartProducts, setCartProducts] = useState([]);

    function getProductQuantity(id) {
        const quantity = cartProducts.find(product => product.id === id)?.quantity;
        
        if (quantity === undefined) {
            return 0;
        }

        return quantity;
    }

    function addOneToCart(id) {
        const quantity = getProductQuantity(id);

        if (quantity === 0) {
            setCartProducts(
                [
                    ...cartProducts,
                    {
                        id: id,
                        quantity: 1
                    }
                ]
            )
        } else { // is in cart
            setCartProducts(
                cartProducts.map(
                    product =>
                    product.id === id                               
                    ? { ...product, quantity: product.quantity + 1 }
                    : product                                       
                )
            )
        }
    }
    
    function removeOneFromCart(id) {
        const quantity = getProductQuantity(id);

        if (quantity === 1) {
            deleteFromCart(id);
        } else {
            setCartProducts(
                cartProducts.map(
                    product =>
                    product.id === id                               
                    ? { ...product, quantity: product.quantity - 1 }
                    : product                                       
                )
            )
        }
    }

    function deleteFromCart(id) {
        setCartProducts(
            cartProducts =>
            cartProducts.filter(currentProduct => {
                return currentProduct.id !== id;
            })
        )
    }

    function getTotalCost() {
        let totalCost = 0;
        cartProducts.map((cartItem) => {
            const productData = getProductData(cartItem.id);
            totalCost += (productData.price * cartItem.quantity);
        });
        return totalCost;
    }

    const contextValue = {
        items: cartProducts,
        getProductQuantity,
        addOneToCart,
        removeOneFromCart,
        deleteFromCart,
        getTotalCost
    }

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

export default CartProvider;
eqqqjvef

eqqqjvef1#

应该使用上下文来管理购物车内部状态,并使用本地存储来保持购物车状态的持久性(或者可以使用会话存储方法)。

localStorage.setItem('cart', JSON.stringify(newCartProductsArray))

并且在添加/删除函数上更新它,则更新函数应该覆盖相同的键值。
要在刷新后恢复状态,请使用CartProvider内的useEffect挂钩。

useEffect(() => {
  const savedCartState = JSON.parse(localStorage.getItem('cart'));
  setCartProducts(savedCartState);
}, []);

相关问题