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}addToCart(product)} /> ); };
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
- El carrito actualiza su estado globalmente y refleja cambios en tiempo real.
- Los items del carrito se persisten localmente al reiniciar la app.
- El checkout incluye validación de datos del usuario y un resumen claro de la compra.
- Se manejan correctamente los totales, incluyendo impuestos y envío si aplican.
- La UI es responsive y funciona bien en iOS y Android.
- Hay feedback visual al agregar items o procesar el pago.
- 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:
- Crea un nuevo proyecto Expo o usa uno existente del módulo.
- Implementa el CartContext mostrado arriba, añadiendo un método para actualizar cantidades.
- Usa AsyncStorage para guardar y cargar el carrito al iniciar la app. Tip: hazlo en un useEffect en CartProvider.
- 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.
- Añade un badge en el header con la cantidad total de items en el carrito.
- Prueba en un emulador y dispositivo físico.
- 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.