Saltar al contenido

Lección 17 de 20 · Lectura y práctica

Implementación de carrito de compras y checkout

Concepto claveEl carrito de compras y checkout son el corazón de cualquier app de comercio electrónico. Imagina un carrito de supermercado físico: los usuarios van agregando productos mientras navegan, pueden revisar lo que.

Del concepto a la práctica

Taller de esta lección

El carrito debe distinguir línea de producto y cantidad. Al agregar un producto existente, incrementa su cantidad; al agregar uno nuevo, crea una línea. El subtotal es la suma de precio unitario × cantidad; el checkout no debe mezclar ese cálculo con validación de dirección o correo.

Ejemplo resuelto

Datos: cuaderno 4,00 × 2 = 8,00; lápiz 1,50 × 3 = 4,50. Subtotal = 12,50. Si el envío fijo es 2,00, total = 14,50. Todas las cifras usan euros.

Pruébalo

  1. Añade cuaderno dos veces.

  2. Añade tres lápices mediante ajuste de cantidad.

  3. Calcula cada importe de línea.

  4. Valida checkout antes de continuar.

Error frecuente: sumar 4,00 y 1,50 ignorando cantidades. Corrige calculando por línea y luego sumando.

Ejercicio: usa exactamente los datos anteriores.

Comprueba tu resultado

dos líneas, cantidades 2 y 3, subtotal 12,50 y total con envío 14,50; quitar una unidad de lápiz deja subtotal 11,00.

Céntimos, stock y subtotal calculado

javascript
const catalogo=[{id:'p1',nombre:'Cuaderno',precio:400,stock:4},
 {id:'p2',nombre:'Lápiz',precio:150,stock:10},{id:'p3',nombre:'Goma',precio:100,stock:0}];
function calcularPedido(lineas){
  if(!Array.isArray(lineas)||lineas.length===0) throw new Error('Carrito vacío');
  const vistos=new Set();
  const subtotal=lineas.reduce((sum,linea)=>{
    if(!linea||vistos.has(linea.id)) throw new Error('ID repetido o inválido');
    vistos.add(linea.id);
    const p=catalogo.find(p=>p.id===linea.id);
    if(!p||!Number.isInteger(linea.qty)||linea.qty<=0||linea.qty>p.stock) throw new Error('Cantidad o stock inválido');
    return sum+p.precio*linea.qty;
  },0);
  return {subtotal,envio:200,total:subtotal+200};
}

Todos los importes son enteros en céntimos de EUR de este laboratorio; no hay impuestos ni descuentos en este caso. Con p1/2 y p2/3: subtotal1250,envío200,total1450. Al quitar un lápiz quedan p2/2:subtotal1100,total1300. p3/1,qty0,qty1.5,p9 e IDs repetidos fallan antes del cobro. Para eliminar una línea usa una acción explícita en vez de almacenar qty0. No muta las líneas; estado anterior se conserva si falla. La pantalla puede orientar con stock local y el backend debe verificarlo otra vez antes de crear pedido.

Catálogo, carrito y confirmación distinguen selección local de precio y pedido validados por el servidor.
CursaloMapa de práctica
Un carrito con datos coherentes

El carrito local expresa la selección de la persona. El servidor valida disponibilidad, precio y operación antes de confirmar el pedido; una pantalla local de éxito no prueba que haya existido cobro o compra.

Ver la infografía en tamaño completo ↗

Concepto clave

El carrito de compras y checkout son el corazón de cualquier app de comercio electrónico. Imagina un carrito de supermercado físico: los usuarios van agregando productos mientras navegan, pueden revisar lo que tienen antes de pagar, y finalmente completan la transacción en la caja. En React Native, implementamos esto gestionando el estado de los productos seleccionados, calculando totales en tiempo real, y guiando al usuario a través de un flujo seguro de pago.

La clave está en separar responsabilidades: el carrito maneja la selección temporal de productos, mientras el checkout procesa la información del usuario y la transacción. Usamos Context API o Redux para compartir el estado del carrito entre componentes sin prop drilling, similar a como una tienda física tiene un sistema centralizado que todas las cajas pueden consultar.

Cómo funciona en la práctica

Vamos a construir un carrito paso a paso. Primero, crea un contexto para el carrito que almacene los items, cantidades, y métodos para agregar/eliminar. Luego, en cada producto de tu catálogo, añade un botón "Agregar al carrito" que dispare una acción para actualizar ese contexto. Finalmente, crea una pantalla de checkout que muestre un resumen, campos para dirección y pago, y un botón de confirmación.

Un flujo típico: 1) Usuario toca "Agregar" en un producto, 2) El item se añade al estado global del carrito, 3) Un icono en el header muestra la cantidad de items, 4) Al navegar al carrito, se listan los productos con opciones para modificar cantidad, 5) En checkout, se validan los datos del usuario antes de enviar la orden a un backend.

Código en acción

Aquí un ejemplo básico del contexto del carrito usando React Context:

import React, { createContext, useState, useContext } from 'react';

const CartContext = createContext();

export const CartProvider = ({ children }) => {
  const [cartItems, setCartItems] = useState([]);

  const addToCart = (product) => {
    setCartItems(prev => {
      const existing = prev.find(item => item.id === product.id);
      if (existing) {
        return prev.map(item =>
          item.id === product.id
            ? { ...item, quantity: item.quantity + 1 }
            : item
        );
      }
      return [...prev, { ...product, quantity: 1 }];
    });
  };

  const removeFromCart = (productId) => {
    setCartItems(prev => prev.filter(item => item.id !== productId));
  };

  const total = cartItems.reduce((sum, item) => sum + (item.price * item.quantity), 0);

  return (
    
      {children}
    
  );
};

export const useCart = () => useContext(CartContext);

Y así lo usas en un componente de producto:

import { useCart } from '../context/CartContext';

const ProductItem = ({ product }) => {
  const { addToCart } = useCart();

  return (
    
      {product.name}
      ${product.price}
      
  );
};

Errores comunes

  • No persistir el carrito al cerrar la app: Los usuarios esperan que sus items se mantengan. Usa AsyncStorage o una base de datos local para guardar el estado.
  • Calcular totales incorrectamente: Olvidar incluir impuestos, envío, o descuentos. Siempre recalcula en tiempo real basado en el estado actual.
  • Falta de validación en checkout: No verificar campos como email o tarjeta de crédito antes de enviar. Usa librerías como Formik o validación manual.
  • No manejar estados de carga y error: Durante el pago, muestra spinners y mensajes claros si falla la transacción.
  • Ignorar la experiencia en pantallas pequeñas: En móviles, el checkout debe ser un flujo vertical simple, sin scroll horizontal.

Checklist de dominio

  1. El carrito actualiza su estado globalmente y refleja cambios en tiempo real.
  2. Los items del carrito se persisten localmente al reiniciar la app.
  3. El checkout incluye validación de datos del usuario y un resumen claro de la compra.
  4. Se manejan correctamente los totales, incluyendo impuestos y envío si aplican.
  5. La UI es responsive y funciona bien en iOS y Android.
  6. Hay feedback visual al agregar items o procesar el pago.
  7. El código está organizado, con el contexto del carrito separado de la lógica de UI.

Implementa un carrito con persistencia y checkout básico

Sigue estos pasos para extender el ejemplo del carrito:

  1. Crea un nuevo proyecto Expo o usa uno existente del módulo.
  2. Implementa el CartContext mostrado arriba, añadiendo un método para actualizar cantidades.
  3. Usa AsyncStorage para guardar y cargar el carrito al iniciar la app. Tip: hazlo en un useEffect en CartProvider.
  4. Crea una pantalla de checkout con:
    • Un listado de items del carrito con opción de eliminar.
    • Campos para nombre, email, y dirección (puedes simular pago).
    • Un botón "Comprar" que muestre un alert de confirmación y limpie el carrito.
  5. Añade un badge en el header con la cantidad total de items en el carrito.
  6. Prueba en un emulador y dispositivo físico.
Pistas
  • Usa AsyncStorage.setItem y AsyncStorage.getItem para persistencia.
  • Para el badge, puedes usar un estado derivado del contexto en tu header.
  • Valida el email con una expresión regular simple en el checkout.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.

Sigue con React Native y Expo: Interfaces, Estado y APIs de Dispositivo

Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.

Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.

01 / ELEGIR UNA RUTA

El próximo paso

Aprende IA mientras construyes algo que sí necesitas.

Empieza por el curso inicial o explora el catálogo para encontrar una práctica alineada con tu trabajo.