Saltar al contenido

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

Implementación de pantallas principales: catálogo, carrito y perfil

Tipo de lección: VideoConcepto claveEn el desarrollo de apps de e-commerce móvil con React Native y Expo, las pantallas principales (catálogo, carrito y perfil) son el esqueleto funcional que determina la experiencia del usuario..

Del concepto a la práctica

Taller de esta lección

Las tres pantallas deben compartir una regla de datos: el catálogo conoce productos, el carrito conoce cantidades y el perfil conoce la sesión simulada. El importe de una línea es cantidad por precio unitario; no uses el número de artículos como precio.

Ejemplo resuelto

  1. Define p1 a 4.00 con cantidad 2 y p2 a 7.50 con cantidad 1.

  2. Muestra tarjetas del catálogo y una acción para añadir.

  3. En el carrito, calcula 2 × 4.00 + 1 × 7.50.

  4. En el perfil, muestra una sesión ficticia sin incluir credenciales. Un error frecuente es sumar 4.00 y 7.50 ignorando cantidades. Corrígelo calculando cada línea y luego el total: 8.00 + 7.50 = 15.50.

Pruébalo

Añade los dos productos anteriores y elimina una unidad de p1.

Comprueba tu resultado

El carrito debe mostrar p1 con cantidad 1, p2 con cantidad 1 y subtotal 11.50; el catálogo no debe perder sus dos registros.

Cálculo puro e hidratación sin sobrescribir

Este laboratorio usa el catálogo común con importes enteros; no simula un cobro.

javascript
const PRECIOS={p1:400,p2:750,p3:225,p4:1000};
function subtotal(items){
  if(items.some(x=>!Object.hasOwn(PRECIOS,x.id)||!Number.isSafeInteger(x.quantity)||x.quantity<1)||new Set(items.map(x=>x.id)).size!==items.length) throw new Error('Carrito inválido');
  const total=items.reduce((sum,x)=>sum+PRECIOS[x.id]*x.quantity,0);
  if(!Number.isSafeInteger(total)) throw new Error('Importe fuera de rango');
  return total;
}

p1×2+p2×1 da1550centavos,15.50; disminuir p1 a1 da1150,11.50. Eliminar una unidad significa decrementar y solo retirar la línea al llegar a0; la función removeFromCart del original elimina toda la línea y no equivale a esa acción. Valida también stock al cambiar cantidades. El perfil muestra Demo, sin contraseñas ni token.

Si persistes carrito en AsyncStorage, no guardes [] hasta terminar la lectura inicial. Valida JSON/forma/IDs/cantidades y bloquea edición durante hidratación o combina con un contrato explícito. Secuencia de escrituras para no dejar una versión antigua por resolución fuera de orden; captura fallos y avisa si no se guardó. AsyncStorage no pide un permiso nativo ordinario y no cifra secretos. Prueba JSON válido, corrupto, lectura fallida y reapertura antes de declarar persistencia.

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 ↗

Tipo de lección: Video

Concepto clave

En el desarrollo de apps de e-commerce móvil con React Native y Expo, las pantallas principales (catálogo, carrito y perfil) son el esqueleto funcional que determina la experiencia del usuario. Piensa en ellas como las tres secciones principales de una tienda física: el catálogo es el área de exhibición donde los clientes exploran productos, el carrito es el espacio temporal donde guardan lo que quieren comprar, y el perfil es la caja registradora donde finalizan la transacción y gestionan su cuenta. Implementar estas pantallas no solo implica crear interfaces visuales, sino también manejar estado global (como los items en el carrito) y navegación fluida entre secciones, asegurando que los datos persistan y se actualicen en tiempo real.

Para un nivel intermedio, es crucial entender que estas pantallas deben ser componentes reutilizables y optimizados para rendimiento. Por ejemplo, el catálogo debe cargar productos de forma paginada para evitar lentitudes, el carrito debe sincronizarse con un backend o almacenamiento local, y el perfil debe gestionar autenticación y preferencias del usuario. Usar herramientas como React Navigation para la navegación y Context API o Redux para el estado global te permitirá construir una app escalable y mantenible, similar a cómo una cadena de tiendas estandariza sus procesos para operar eficientemente en múltiples ubicaciones.

Cómo funciona en la práctica

Vamos a implementar las pantallas principales paso a paso en un proyecto de Expo. Primero, configura la navegación usando React Navigation: instala las dependencias con npx expo install @react-navigation/native @react-navigation/stack y crea un navegador de pila con tres pantallas. Luego, diseña cada pantalla como un componente funcional de React: el catálogo mostrará una lista de productos obtenidos de una API, el carrito listará items agregados desde el catálogo, y el perfil mostrará información del usuario. Para manejar el estado del carrito, usa Context API: crea un contexto que almacene los items y funciones para agregar o eliminar, y provéelo en toda la app.

Un flujo típico es: el usuario navega al catálogo, toca un producto para ver detalles, lo agrega al carrito (actualizando el estado global), luego va al carrito para revisar y proceder al checkout, y finalmente accede al perfil para ver historial de compras. Implementa esto con useEffect para cargar datos asíncronos y FlatList para renderizar listas eficientes. Asegúrate de probar en ambos iOS y Android, ajustando estilos con StyleSheet para consistencia cross-platform.

Código en acción

Aquí tienes un ejemplo funcional de cómo crear el contexto del carrito y usarlo en la pantalla de catálogo:

// CartContext.js
import React, { createContext, useState, useContext } from 'react';

export const CartContext = createContext();

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

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

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

  return (
    
      {children}
    
  );
};

export const useCart = () => useContext(CartContext);
// CatalogScreen.js
import React from 'react';
import { View, Text, FlatList, TouchableOpacity, StyleSheet } from 'react-native';
import { useCart } from './CartContext';

const CatalogScreen = () => {
  const { addToCart } = useCart();
  const [products, setProducts] = React.useState([
    { id: 1, name: 'Producto A', price: 19.99 },
    { id: 2, name: 'Producto B', price: 29.99 },
  ]);

  const renderProduct = ({ item }) => (
    
      {item.name}
      ${item.price.toFixed(2)}
       addToCart(item)}>
        Agregar al carrito
      
    
  );

  return (
     item.id.toString()}
      contentContainerStyle={styles.list}
    />
  );
};

const styles = StyleSheet.create({
  productContainer: { padding: 16, borderBottomWidth: 1, borderColor: '#ccc' },
  productName: { fontSize: 18, fontWeight: 'bold' },
  productPrice: { fontSize: 16, color: 'green', marginVertical: 8 },
  addButton: { backgroundColor: '#007AFF', padding: 10, borderRadius: 5 },
  buttonText: { color: 'white', textAlign: 'center' },
  list: { paddingBottom: 20 }
});

export default CatalogScreen;

Errores comunes

  • No optimizar listas grandes en el catálogo: Usar ScrollView en lugar de FlatList puede causar lentitud. Siempre usa FlatList o SectionList para listas con muchos items, implementando paginación si es necesario.
  • Manejar estado del carrito solo localmente: Si no usas Context API o Redux, el estado no se compartirá entre pantallas. Asegúrate de centralizar el estado global para que el carrito se actualice en todas las pantallas.
  • Olvidar la persistencia de datos: Al cerrar la app, el carrito se perderá si no lo guardas. Usa AsyncStorage o una base de datos local para persistir el estado entre sesiones.
  • Ignorar diferencias entre iOS y Android: Los estilos y componentes pueden verse distintos. Prueba en ambos dispositivos y usa Platform.OS para ajustes específicos, como paddings o fuentes.
  • No validar entradas en el perfil: En pantallas de perfil con formularios, falta validar emails o contraseñas puede llevar a errores de seguridad. Implementa validación cliente y servidor.

Checklist de dominio

  1. Configuré React Navigation para navegar entre catálogo, carrito y perfil sin recargar la app.
  2. Implementé un contexto global (Context API o Redux) para manejar el estado del carrito.
  3. Usé FlatList en el catálogo para renderizar productos de forma eficiente, con carga paginada si es necesario.
  4. Agregué funcionalidad para añadir y eliminar items del carrito, con actualización en tiempo real.
  5. Diseñé la pantalla de perfil con secciones para datos de usuario, historial de compras y configuración.
  6. Persistí el estado del carrito usando AsyncStorage para mantener datos entre sesiones.
  7. Probé la app en simuladores de iOS y Android, ajustando estilos para consistencia cross-platform.

Implementa un carrito de compras con persistencia y navegación

Sigue estos pasos para crear una app de e-commerce móvil con las tres pantallas principales:

  1. Configura el proyecto: Crea un nuevo proyecto Expo con npx create-expo-app ecommerce-app e instala React Navigation y AsyncStorage.
  2. Crea el contexto del carrito: Implementa un contexto similar al ejemplo de código, añadiendo una función para calcular el total del carrito.
  3. Desarrolla la pantalla de catálogo: Usa FlatList para mostrar al menos 10 productos mockeados, cada uno con un botón para agregar al carrito.
  4. Desarrolla la pantalla de carrito: Muestra los items del carrito con cantidad y precio, botones para eliminar, y el total. Usa el contexto para acceder a los datos.
  5. Desarrolla la pantalla de perfil: Incluye un formulario simple para nombre y email, y una lista de últimas compras (puedes mockear datos).
  6. Implementa persistencia: Guarda el carrito en AsyncStorage al cambiar y cárgalo al iniciar la app.
  7. Conecta la navegación: Usa un TabNavigator para cambiar entre las tres pantallas y prueba en iOS y Android.
Pistas
  • Usa useEffect en el contexto para guardar y cargar el carrito desde AsyncStorage.
  • Para el catálogo, considera usar useState para manejar la paginación si agregas muchos productos.
  • En el perfil, valida el email con una expresión regular simple antes de guardar.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.

Sigue con React Native con Expo: Desarrollo de Apps Nativas para iOS y Android

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.