Luis Eduardo Sotoj Teque
Miguel Gutiérrez
Héroe! y por que no fue necesario hacer esto en la card?
Ellioth Aguirre Gonzales
genio
¿Cómo se agregan los productos al carrito de compras en un e-commerce?
En el excitante mundo del desarrollo de aplicaciones de e-commerce, una de las funcionalidades más vitales es el carrito de compras. Un carrito de compras bien diseñado permite a los usuarios revisar y gestionar los productos seleccionados para compra. En esta sesión, aprenderemos cómo implementar esta funcionalidad básica de agregar productos al carrito cuando se hace clic en el botón correspondiente en un e-commerce.
¿Qué pasos se deben seguir para crear la funcionalidad del carrito?
Creación del Side Menu: Primero, se debe establecer un menú lateral para gestionar el carrito de compras. Este menú facilita la visualización y administración de los productos añadidos.
Añadir productos al carrito: Se comienza definiendo el estado global en el que se almacenarán los productos seleccionados. Es crucial que este estado se mantenga actualizado cada vez que se agregue un producto al carrito:
const [cartProducts, setCartProducts] = useState([]);
Implementar la lógica para actualizar el estado: Cada vez que el usuario hace clic en el icono de añadir, se debe ejecutar una función que actualice el estado del carrito:
const addProductsToCart = (productData) => { setCartProducts((prevCartProducts) => [...prevCartProducts, productData]); };
Integrar el código para el evento 'onclick':
En el componente del producto, añadimos la funcionalidad haciendo uso de un controlador de eventos 'onclick' que llame a la función addProductsToCart:
<div onClick={() => addProductsToCart(productData)}> <PlusIcon /> </div>
¿Cómo manejar las imágenes y datos del producto?
Es común que la API de productos utilice imágenes aleatorias, lo que puede causar confusión al añadir productos al carrito. Es importante basar la lógica en datos consistentes como el precio y el nombre, asegurando así la identidad del producto:
¿Cómo optimizar el código para garantizar un buen desempeño?
cartProducts cada vez que se añaden nuevos productos.¿Qué sigue después de agregar los productos al carrito?
Una vez establecida esta funcionalidad, el siguiente paso es crear un componente de vista preliminar, o mini carrito, para que los usuarios tengan una vista rápida de los productos en su carrito desde cualquier parte de la aplicación. Este desarrollo propicia una experiencia de usuario fluida y mejorada.
Esta implementación no solo es esencial, sino que es una base robusta para construir un e-commerce funcional y orientado al usuario. Entender y manipular estos conceptos te acerca un paso más a dominar el desarrollo web moderno. ¡Continúa explorando y mejorando tus habilidades!
Luis Eduardo Sotoj Teque
Miguel Gutiérrez
Héroe! y por que no fue necesario hacer esto en la card?
Ellioth Aguirre Gonzales
genio
Miguel Angel Reyes Moreno
Una gran recomendación, instalen las extensiones de React Developer Tools, React Context DevTool y Redux DevTools para ver toda la información de la aplicación SIN necesidad de hacer console.log. No está mal hacer console.log, pero creo que puede servir también bastante utilizar estas herramientas y nos ahorramos aunque sea un poco de código 😃
Juan Fernando Lopez
tambien para que puedan descargar pesticide, te dice como va e html y css solo con hacer hoover
JOSE FABIAN BONILLA GUZMAN
como es lo de pestice perdon es que no se si es la que encontre
que bueno que lo mencionas, realmente eso de data.data no lo realize.... mi componente card esta con la porp data destructurado y de hecho el useContext (para no perder las viejas costumber jejeje) es igual a un objeto con el nombre de los estados y funciones... te muestro mi codigo, a mi parecer es mejor asi...
const Card = ({ data }) => { const { count, setCount, openProductDetail, setProductToShow, } = useContext(shoppingCartContext);
no llamas data(punto), ni ha context(punto) bueno gustos son gustos me siento mejor con esta sintaxis:
Sebastian Rodriguez
La razon de que no salga en consola el primer producto que estefany agrega al carrito es por la posicion donde esta ese console.log(), si lo ponemos en el context justo debajo del estado del carrito de compras si nos muestra ambos productos. Es como si el estado no se terminara de actualizar (setCartProducts), hasta que se cierra la funcion addProductsToCart
Camilo Andrés Granda Cortés
Sí, podría hacerse con un useEffect.
Luis Miguel Aponte Rayo
SIgo sin entender bro, deberia mostrarse no? porque el console.log esta debajo del setCart
david jurado
No sé que tan bien esté, pero yo solucioné el problema del objeto de product detail poniendo el condicional &&, así si no existe ese arreglo ni siquiera me carga el componente, por lo que si tengo images[0] no me dará error, ya que lo carga hasta que haya algo
david jurado
Pueden usar el condicional en el componente padre solo que como uso next intento usarlo en el mas pequeño para poner 'use client'
Santiago López Alarcón
Pueden colocar el siguienet codigo para que la imagen de Product Detail sea igual a la que muestran en la Card:
const [productToShow, setProductToShow] = useState({ title: "", price: "", description: "", images: [], });
Les dejo un Pantallazo:
Martín Tamagno
Exacto, me llamó la atención que Teff utilizó al inicio de la clase de sacar el index del array de images, pero en realidad lo que estaba pasando, es que al iniciar la app, por más que el ProductDetail no se muestre, igual estaba intentando asignar la información a los elementos de ese componente. También me incliné por tu solución, de asignar un objeto vacío al inicializar el estado de Product Detail, pero con las properties que espera!
David Gaspar
Soy yo o la API dejó de funcionar
Carlos Daniel Dominguez
Pana si. A la fecha a mi también me dejó de funcionar, ya de por si me estaba dando problemas y no me generaba mucha confianza. Usa la FakeStoreApi que cumple casi la misma función
Jordy alfredo Gutierrez Fernandez
La API de Platzi Fake Store API esta rota a la fecha 8/mayo/2024. Mi aplicacion dejo de cargar toda la informacion y revisando el contenido de la API, claramente alguien estuvo jugando con ella
Rubén Ernesto Aragón Gil
David Higuera
Opcionalmente se puede enviar una funcion a los setters de los estados, en lugar de el valor directo:
const onIncrementClick = (e) => { e.stopPropagation(); setCartItems((items) => [...items, data]); incrementCount(); };
Dicha funcion recibe como argumento el valor actual del estado
Xavier Flores
mi código escrito en TS:
Oscar Ramírez Abreu
intenta
src={context.productToShow?.images?.[0]}
Santiago Tamayo Perez
Me pueden ayudar con este error he seguido tal cual el paso a paso de la profe, y em dice que no es una función. me ayudan por fa
Edwin Hernández Camacho
¿Podrías pasar una foto de tu código en el archivo Card.jsx para ver como estas importando?
Mientras tanto re recomiendo, ver si estás importando la ruta correctamente del shoppingCartContext al archivo Cart.jsx. Otra opción es que si lo estás importando bien y la función existe en el shoppingCartContext.jsx, pero si no te la reconoce, puede ser que al final de ese shoppingCartContext.jsx no estés exportando el productToShow y por eso no te lo reconoce como una función. Y ya por último a veces es problema del hot reload, corre nuevamente en la consola npm run dev y puede que se arregle
Me cuentas como te va 👋
Agustina Corvo
Para los que vienen teniendo problemas con la API, les recomiendo pasarse a que es más estable
William Armando Forero Bermeo
Muchas gracias Agustina !
Andres Felipe Vargas Gonzalez
Hoy 1/13/2025 han dado de baja casi que todos los elementos de la API D: solo hay un Item
Christian Leon
Para los que no entienden el por qué no se puede ver en la consola el nuevo valor del estado, les dejo la explicación y el link a la documentación que habla de esto:
Link:
Explicación: lo que sucede es que cuando se actualiza un estado, se corre un proceso que no modifica el estado (cartItems en mi caso) en el controlador de evento que ya se está ejecutando (addItemToCar en mi caso). Si necesitas usar el siguiente estado, puedes guardarlo en una variable (cart en mi caso) antes de pasarlo a la función de actualización:
const addItemToCar = (product: Product) => { const cart = [...cartItems, product]; console.log('cart: ', cart); setCartItems([...cartItems, product]); console.log('cartItems: ', cartItems); }
Sonia Mendoza
Daniel Morales
Para visualizar de una mejor manera lo que pasa cuando le damos clic a agregar, podemos instalar la extensión de React en nuestro navegador, en este caso estoy utilizando Firefox y así se ve cuando el estado se actualiza.
Juan Manuel Navarro González
Una forma más fácil para mi punto de vista de hacerlo, importando también los estados en nuestro archivo Card con useContext.
<PlusCircleIcon className="absolute text-sm top-1 right-1 flex justify-center items-center bg-white/90 rounded-full w-6 h-6" onClick={() => { setCount(count + 1) setAddCartProducts([...addCartProducts, data.data]) console.log(addCartProducts) }} />
Para solucionar el error que ocurre en el arreglo de imágenes pueden utilizar el operador Optional chaining (?.)
?.
Ejemplo de cómo quedaría el código accediendo a la imagen:
<img className="w-full h-full rounded-lg" src={context.productToShow.images?.[0]} alt={context.productToShow.title} />
Este operador se utiliza para acceder a propiedades de objetos anidados de forma segura, evitando errores si alguna de las propiedades no está definida o es nula.
const Card = (data) => { const context = useContext(ShoppingCartContext) const showProduct = (productDetail) => { context.openProductDetail() context.setProductShow(productDetail) } const addProductToCart = (productData) => { context.setCount(context.count + 1) context.setCartProducts([...context.cartProducts, productData]) } return ( <div className="bg-white cursor-pointer w-56 h-60 rounded-lg" onClick={() => showProduct(data.data)}> <figure className="relative mb-2 w-full h-4/5"> <span className="absolute bottom-0 left-0 bg-white/60 rounded-lg text-black text-xs m-2 px-3 py-0.5">{data.data.category.name}</span> <img className="w-full h-full object-cover rounded-lg" src={data.data.images[0]} alt={data.data.title} /> <div className="absolute top-0 right-0 flex justify-center items-center bg-white w-6 h-6 rounded-full m-2 p-1" onClick={() => addProductToCart(data.data)}> <PlusIcon className='h-6 w-6 text-black' /> </div> </figure> <p className="flex justify-between"> <span className="text-sm font-light">{data.data.title}</span> <span className="text-lg font-medium">${data.data.price}</span> </p> </div> ) }
Para que si agregas el mismo producto mas de una vez no se repita el objeto, sino que se empiece a sumar yo hice esto:
const addProductsToCart = (productData) => { setCount(count + 1); const existingProductIndex = shoppingCartProducts.findIndex( (product) => product.id === productData.id ); console.log(existingProductIndex); if (existingProductIndex !== -1) { const updatedShoppingCartProducts = [...shoppingCartProducts]; updatedShoppingCartProducts[existingProductIndex].qty += 1; setShoppingCartProducts(updatedShoppingCartProducts); } else { const productWithQty = { ...productData, qty: 1 }; const shoppingCartProductsCopy = [ ...shoppingCartProducts, productWithQty, ]; setShoppingCartProducts(shoppingCartProductsCopy); } console.log(shoppingCartProducts); }; ```