Orden de compra

Clase 24 de 30Curso de React 17 con Webpack 5 y Sass

Resumen

Integrar un panel de checkout que muestre los productos agregados al carrito es uno de los pasos más satisfactorios cuando construyes una tienda con React. Aquí se aborda cómo reutilizar la lógica de toggle, consumir el estado global con Context API y renderizar dinámicamente cada producto seleccionado, todo sin perder de vista las buenas prácticas de identificación de elementos.

¿Cómo crear el toggle para mostrar las órdenes?

El punto de partida es el componente Header, donde ya existía un toggle para el menú. La misma estrategia se replica ahora para el panel de órdenes [0:12].

  • Se declara una nueva constante con useState: const [toggleOrders, setToggleOrders] = useState(false);.
  • El estado arranca en false, lo que significa que el panel permanece oculto hasta que el usuario interactúe.
  • Se importa el componente MyOrder desde la carpeta de contenedores: import MyOrder from './containers/MyOrder';.

Para renderizar condicionalmente el componente se utiliza el operador && (short circuit evaluation): cuando toggleOrders es true, React monta <MyOrder /> [1:38].

¿Por qué convertir el handler en función anónima?

Un error común es pasar directamente la invocación de setToggleOrders(!toggleOrders) dentro del atributo onClick. Esto provoca que la función se ejecute en cada render, generando un bucle infinito de re-renderizados [4:08]. La solución es envolver la llamada en una función anónima:

jsx onClick={() => setToggleOrders(!toggleOrders)}

De esta forma, la función solo se dispara cuando el usuario hace clic. Es un detalle sutil pero crítico: si no se inicializan correctamente los handlers, la aplicación puede romperse sin una razón aparente en consola.

¿Qué estilos necesita el panel de órdenes?

Para que MyOrder se presente correctamente, se ajustan los estilos en su archivo CSS correspondiente [2:40]:

  • background-color: blanco, para contrastar con el resto de la interfaz.
  • top: 60px, separando el panel del borde superior donde vive el Header.
  • bottom: 0, asegurando que ocupe hasta el final de la ventana.
  • border-radius: 6px, siguiendo las especificaciones del diseño en Figma.
  • border: 1px solid con una variable de color gris definida en las variables globales del proyecto.

Reutilizar variables CSS garantiza consistencia visual y facilita cambios futuros en la paleta de colores.

¿Cómo consumir el estado global con Context API?

Dentro de MyOrder se necesita acceder al arreglo de productos del carrito sin depender de props enviadas desde un componente padre [5:52]. Para lograrlo se utiliza useContext:

jsx import { useContext } from 'react'; import { AppContext } from '../context/AppContext';

const state = useContext(AppContext);

Esta decisión es deliberada: aunque se podría pasar el estado como prop, consumirlo desde el contexto permite que MyOrder funcione de forma independiente. Si en el futuro el componente se renderiza en otra ruta o sin un padre directo, seguirá teniendo acceso a la información del carrito.

¿Cómo iterar los productos del carrito?

Con el estado disponible, se recorre state.cart usando el método map para generar un componente OrderItem por cada producto [7:08]:

jsx {state.cart.map(product => ( <OrderItem key={order-item-${product.id}} product={product} /> ))}

¿Cómo evitar conflictos en las keys de React?

Cuando varias listas comparten IDs numéricos (por ejemplo, ProductList y la lista de órdenes), React puede confundir los nodos del DOM. La solución es usar template literals para prefijar la key con un nombre descriptivo [7:30]:

js key={order-item-${product.id}}

Así, order-item-1 nunca colisionará con el product-1 de otra lista. Es una práctica recomendada que garantiza unicidad y evita comportamientos inesperados en la reconciliación de React.

Al probar la aplicación, cada clic en "agregar" incrementa el contador y, al abrir el panel, se visualizan todos los productos seleccionados [8:40]. El siguiente paso natural sería calcular el total del pedido y permitir eliminar elementos individuales. ¿Qué estrategia usarías tú para la función de eliminación: filtrar por ID o por índice? Comparte tu enfoque.

      Orden de compra