Jak zachować koszyk pomiędzy wielokrotnymi wczytaniami strony?

Jak zachować koszyk pomiędzy wielokrotnymi wczytaniami strony?

Wątek przeniesiony 2024-11-21 10:41 z JavaScript przez Riddle.

Cezary Szczepaniak
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3
1

Witam , mam problem próbuje dodać local storage do mojego koszyka aby po odswieżeniu strony nie usuwał się po wielu próbach nie działa mi to tutaj kod reacta w którym jest koszyk

Kopiuj
import React, { useEffect, useState, useMemo, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import "./header.scss";
import CartIcon from "./cart.icon";
import logo from "./logo.png";
import napis from "./Napis.png";

const Header = ({ cart, clearCart }) => {
  const [cartState, setCartState] = useState(false);
  const [localCart, setLocalCart] = useState([]);
  const [discountCode, setDiscountCode] = useState("");
  const [discountPercentage, setDiscountPercentage] = useState(0);

  const navigate = useNavigate();
  const cartClick = () => setCartState((prev) => !prev);

  const getTotalPrice = useMemo(() => {
    if (!localCart.length) return "0.00";
    const total = localCart.reduce(
      (acc, product) => acc + product.totalPrice,
      0
    );
    const discountedTotal = total * (1 - discountPercentage / 100);
    return discountedTotal.toFixed(2);
  }, [localCart, discountPercentage]);

  const handleDiscountCodeChange = (e) => setDiscountCode(e.target.value);

  const applyDiscount = () => {
    setDiscountPercentage(discountCode === "HELLO10" ? 10 : 0);
  };

  const resetCartButton = () => {
    clearCart();
    setLocalCart([]);
    setDiscountPercentage(0);
    setDiscountCode("");
  };

  const setupCart = useCallback(() => {
    const itemMap = new Map();
    cart.forEach((product) => {
      const { id, name, discountPrice, originalPrice, thumbnail } = product;
      const priceToUse = discountPrice || originalPrice;

      if (itemMap.has(id)) {
        const existingItem = itemMap.get(id);
        existingItem.quantity += 1;
        existingItem.totalPrice += priceToUse;
      } else {
        itemMap.set(id, {
          id,
          name,
          price: priceToUse,
          totalPrice: priceToUse,
          quantity: 1,
          description: product.description || "Brak opisu produktu",
          img: thumbnail || "https://example.com/default-thumbnail.jpg",
        });
      }
    });
    setLocalCart(Array.from(itemMap.values()));
  }, [cart]);

  useEffect(() => {
    setupCart();
  }, [setupCart]);

  const handleCheckout = async () => {
    try {
      const response = await fetch("http://localhost:5000/xd", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ cartItems: localCart }),
      });

      if (!response.ok) {
        throw new Error("Błąd podczas tworzenia sesji Stripe");
      }

      const { url } = await response.json();
      window.location.href = url;
    } catch (error) {
      console.error("Błąd podczas obsługi checkout:", error);
    }
  };

  const goToCheckout = () =>
    navigate("/checkout", {
      state: {
        localCart,
        getTotalPrice,
      },
    });

  return (
    <div className="app-header-container">
      <header>
        <div className="header container">
          <a href="/">
            <img src={logo} alt="Logo" />
          </a>
          <img src={napis} alt="Napis" />
          <div onClick={cartClick}>
            <CartIcon width={40} />
          </div>
        </div>
      </header>

      {cartState && (
        <div className="cart animate__animated animate__fadeIn">
          <h2>Koszyk</h2>
          {localCart.length === 0 ? (
            <p>Twój koszyk jest pusty.</p>
          ) : (
            localCart.map((product) => (
              <div key={product.id} className="cart-item">
                <div className="product-details">
                  <p className="product-name">{product.name}</p>
                  <div className="quantity-control">
                    <span className="product-quantity">
                      Ilość: {product.quantity}
                    </span>
                    <span className="product-quantity">
                      Cena za sztukę: {product.price} PLN
                    </span>
                  </div>
                </div>
                <p className="product-total-price">
                  Razem: {product.totalPrice.toFixed(2)} PLN
                </p>
              </div>
            ))
          )}
          <p className="total-price">
            Razem: <br /> {getTotalPrice} PLN
          </p>
          <div className="discount-code-container">
            <input
              type="text"
              value={discountCode}
              onChange={handleDiscountCodeChange}
              placeholder="Wpisz kod rabatowy"
            />
            <button onClick={applyDiscount}>Zastosuj rabat</button>
            <button onClick={resetCartButton}>Wyczyść koszyk</button>
          </div>
          {discountPercentage > 0 && (
            <p className="discount-info">
              Zastosowano rabat: {discountPercentage}%
            </p>
          )}
          <button onClick={handleCheckout} className="submit-button">
            Przejdź do płatności
          </button>
          <button onClick={goToCheckout} className="submit-button">
            Przejdź do podsumowania
          </button>
        </div>
      )}
    </div>
  );
};

export default Header;

Z góry dziękuje za pomoc

Riddle
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10297
1

Najlepszym wyjściem byłoby wydzielić osobną funkcję lub klasę która miałaby odpowiadać za pamiętanie koszyka, bo Twój komponent i tak jest duży teraz.

Ale jeśli chcesz to zrobić tak "na brudno", to tam gdzie robisz const [localCart, setLocalCart] = useState([]);, weź początkowy stan z localStorage, a tam gdzie zmieniasz setLocalCart() tam dodatkowo ustaw wartość w localStorage. Ale jak mówiłem - takie mieszanie odpowiedzialności zaraz przestanie się opłacać i zrobi się śmietnik 😄

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.