Creando una carrito simple de compras en React
https://guitarla.inventif.xyz/
1. El Estado Inicial (State)
En React, el «State» es la memoria del componente. Aquí defines qué datos van a cambiar a lo largo del tiempo.
data: Almacena la lista de productos (guitarras) que traes de tu base de datos local (db).cart: Es la lista de productos que el usuario decide comprar.- Constantes de control:
MAX_ITEMSyMIN_ITEMSsirven para poner límites lógicos (por ejemplo, no puedes comprar 0 guitarras o más de 5 del mismo modelo).
2. Persistencia con useEffect
Este bloque es fundamental para que, si el usuario refresca la página, el carrito no se borre.
JavaScript
useEffect(() => {
localStorage.setItem('cart', JSON.stringify(cart))
}, [cart])
- ¿Qué hace?: Cada vez que la variable
cartcambia, React guarda automáticamente el contenido en ellocalStoragedel navegador convertido a texto (JSON).
3. Lógica del Carrito (Las Funciones)
Aquí es donde ocurre la «magia». Analicemos las operaciones principales:
A. Agregar al carrito (addToCart)
No solo añade un objeto, primero verifica: ¿Ya existe este producto?
- Si existe: Aumenta la cantidad (
quantity), pero solo si no ha pasado el máximo permitido. - Si no existe: Crea una copia del producto y le añade la propiedad
quantity: 1.
B. Modificar Cantidades (increaseQuantity y substractionQuantity)
Ambas funciones usan .map(). Este método recorre el carrito y crea uno nuevo modificado:
- Busca el
idcoincidente. - Si lo encuentra, retorna un nuevo objeto con la cantidad alterada.
- Si no es el ID buscado, retorna el producto tal cual estaba.
C. Eliminar y Limpiar
removeFromCart: Usa.filter(). Básicamente dice: «Quédate con todos los productos EXCEPTO el que tenga este ID».clearCart: Simplemente resetea el estado a un arreglo vacío[].
4. El Renderizado (UI)
Finalmente, el componente devuelve el HTML (JSX) que el usuario verá.
| Componente | Responsabilidad | Props enviadas |
| Header | Mostrar el resumen del carrito | cart, funciones de eliminar y modificar cantidad. |
| Guitar | Mostrar la tarjeta de cada producto | guitar (datos), función addToCart. |
Resumen de conceptos clave
- Inmutabilidad: Nunca verás un
cart.push(). Siempre usamossetCart([...cart, nuevoItem])para que React detecte el cambio y repinte la pantalla. - Props Drilling: Estamos pasando funciones desde
Apphacia abajo a los hijos para que ellos puedan «avisarle» al padre cuándo deben cambiar los datos. - Lógica Declarativa: Usamos métodos de arreglos (
map,filter,findIndex) para describir qué queremos que pase con los datos.
import { useEffect, useState } from "react"
import Guitar from "./components/Guitar"
import Header from "./components/Header"
import { db } from "./data/db"
function App() {
const [data, setData] = useState(db)
const [cart, setCart] = useState([])
const MAX_ITEMS = 5
const MIN_ITEMS = 1
useEffect(() => {
localStorage.setItem('cart', JSON.stringify(cart))
}, [cart])
function addToCart(item) {
const itemIndex = cart.findIndex(guitar => guitar.id === item.id)
if (itemIndex >= 0) {
if (cart[itemIndex].quantity >= MAX_ITEMS) return
const updatedCart = [...cart]
updatedCart[itemIndex].quantity++
setCart(updatedCart)
} else {
setCart([...cart, { ...item, quantity: 1 }])
}
}
function removeFromCart(id) {
setCart(prevCart => prevCart.filter(guitar => guitar.id !== id))
}
function increaseQuantity(id) {
const updateCart = cart.map(guitar => {
if (guitar.id === id && guitar.quantity < MAX_ITEMS) {
return {
...guitar,
quantity: guitar.quantity + 1
}
}
return guitar
})
setCart(updateCart)
}
function substractionQuantity(id) {
const updateCart = cart.map(guitar => {
if (guitar.id === id && guitar.quantity > MIN_ITEMS) {
return {
...guitar,
quantity: guitar.quantity - 1
}
}
return guitar
})
setCart(updateCart)
}
function clearCart() {
setCart([])
}
return (
<>
<Header
cart={cart}
removeFromCart={removeFromCart}
increaseQuantity={increaseQuantity}
substractionQuantity={substractionQuantity}
clearCart={clearCart}
/>
<main className="container-xl mt-5">
<h2 className="text-center">Nuestra Colección</h2>
<div className="row mt-5">
{data.map((guitar) => (
<Guitar
key={guitar.id}
guitar={guitar}
cart={cart}
setCart={setCart}
addToCart={addToCart}
increaseQuantity={increaseQuantity}
/>
))
}
</div>
</main>
<footer className="bg-dark mt-5 py-5">
<div className="container-xl">
<p className="text-white text-center fs-4 mt-4 m-md-0">GuitarLA - Todos los derechos Reservados</p>
</div>
</footer>
</>
)
}
export default App