Skip to main content

Overview

The Music Store shopping cart is built using React’s Context API, providing a centralized state management solution for cart operations across the application.

CartContext Provider

The cart functionality is provided through the CartProvider component, which wraps the application and makes cart operations available to all child components.

Implementation

src/context/CartContext/CartContext.jsx
import { createContext, useContext, useState } from "react";

const CartContext = createContext();

export function CartProvider({ children }) {
  const [carrito, setCarrito] = useState([]);
  const [carritoAbierto, setCarritoAbierto] = useState(false);

  const agregarProducto = (producto) => {
    setCarrito(prev => {
      const existe = prev.find(p => p.id === producto.id);
      if (existe) {
        return prev.map(p =>
          p.id === producto.id ? { ...p, cantidad: p.cantidad + 1 } : p
        );
      }
      return [...prev, { ...producto, cantidad: 1 }];
    });
    setCarritoAbierto(true); // abre el panel al agregar
  };

  const quitarProducto = (id) => {
    setCarrito(prev => prev.filter(p => p.id !== id));
  };

  const cambiarCantidad = (id, delta) => {
    setCarrito(prev =>
      prev.map(p =>
        p.id === id
          ? { ...p, cantidad: Math.max(1, p.cantidad + delta) }
          : p
      )
    );
  };

  const total = carrito.reduce((acc, p) => acc + p.precio * p.cantidad, 0);

  return (
    <CartContext.Provider value={{
      carrito,
      carritoAbierto,
      setCarritoAbierto,
      agregarProducto,
      quitarProducto,
      cambiarCantidad,
      total
    }}>
      {children}
    </CartContext.Provider>
  );
}

export function useCart() {
  return useContext(CartContext);
}

State Management

The cart maintains two pieces of state:

carrito

Array of products with their quantities. Each product includes all product data plus a cantidad field.

carritoAbierto

Boolean that controls the visibility of the cart panel. Automatically opens when products are added.

Available Functions

agregarProducto

Adds a product to the cart or increments its quantity if it already exists.
const { agregarProducto } = useCart();

// Usage in ProductoDetalle component
<button onClick={() => agregarProducto(producto)}>
  Agregar al carrito
</button>
Behavior:
  • Checks if the product already exists in the cart by comparing IDs
  • If exists: increments the cantidad by 1
  • If new: adds the product with cantidad: 1
  • Automatically opens the cart panel (setCarritoAbierto(true))

quitarProducto

Removes a product completely from the cart.
const { quitarProducto } = useCart();

// Remove product by ID
quitarProducto(productId);
Parameters:
  • id (number): The product ID to remove

cambiarCantidad

Adjusts the quantity of a product in the cart.
const { cambiarCantidad } = useCart();

// Increase quantity
cambiarCantidad(productId, 1);

// Decrease quantity
cambiarCantidad(productId, -1);
Parameters:
  • id (number): The product ID
  • delta (number): The amount to change (+1 to increase, -1 to decrease)
Behavior:
  • Uses Math.max(1, p.cantidad + delta) to ensure quantity never goes below 1
  • To remove a product completely, use quitarProducto instead

Cart State

Accessing Cart Data

const { carrito, total, carritoAbierto, setCarritoAbierto } = useCart();
  • carrito: Array of products with quantities
  • carritoAbierto: Boolean for panel visibility
  • setCarritoAbierto: Function to manually toggle cart panel
  • agregarProducto: Add or increment product
  • quitarProducto: Remove product completely
  • cambiarCantidad: Adjust product quantity
  • total: Computed total price of all items

Total Calculation

The cart automatically calculates the total price:
const total = carrito.reduce((acc, p) => acc + p.precio * p.cantidad, 0);
This computed value multiplies each product’s precio by its cantidad and sums the results.

Usage Example

Here’s how the cart is used in the ProductoDetalle component:
src/components/productos/ProductosDetalle.jsx
import { useCart } from "../../context/CartContext/CartContext.jsx"

function ProductoDetalle({ productos }) {
  const { id } = useParams();
  const { agregarProducto } = useCart();
  const producto = productos.find(p => p.id === Number(id));

  return (
    <button
      onClick={() => agregarProducto(producto)}
      className="px-8 py-3 bg-white text-black font-semibold rounded-full"
    >
      Agregar al carrito
    </button>
  );
}
The cart panel automatically opens when a product is added, providing immediate visual feedback to the user.

Product Data Structure

Products in the cart contain the following fields:
{
  id: number,
  nombre: string,
  precio: number,
  imagen: string,
  marca: string,
  categoria: string,
  descripcion: string,
  cantidad: number  // Added by cart context
}
The cantidad field is automatically added when products are placed in the cart.

Build docs developers (and LLMs) love