Saltar al contenido

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

Quiz: UI y gestión de estado en React Native

Tipo de lección: QuizConcepto claveEn React Native con Expo, la gestión de estado y la interfaz de usuario avanzada trabajan juntas como el cerebro y los músculos de una app. Imagina que estás construyendo un dashboard.

Del concepto a la práctica

Taller de esta lección

Este quiz integra layout, estado y validación mediante diagnóstico. Ante una interfaz incorrecta, pregunta qué dato cambió, quién lo posee y qué componente debe renderizarlo. La respuesta correcta debe poder verificarse con una entrada pequeña, no con una impresión subjetiva.

Ejemplo resuelto

Si un badge de carrito muestra 1 después de añadir dos productos distintos, revisa si el badge cuenta productos o unidades. Con [p1 cantidad 2, p2 cantidad 1], productos distintos son 2 y unidades totales son 3; ambas métricas son válidas, pero no deben confundirse.

Pruébalo

  1. Define la métrica visible.

  2. Escribe los datos de entrada.

  3. Calcula el valor derivado.

  4. Comprueba que el componente consume la misma fuente.

Error frecuente: guardar en estado un total que puede derivarse y olvidar actualizarlo. Corrige calculándolo desde las líneas, salvo que exista una razón de persistencia documentada.

Ejercicio: con p1:2 y p2:1, responde qué muestra cada badge.

Comprueba tu resultado

badge de productos 2; badge de unidades 3.

Clave de estado, layout y validación

El fixture [{id:'p1',qty:2},{id:'p2',qty:1}] tiene dos líneas y tres unidades: badge por líneas=2, badge por unidades=3. Declara cuál comunica tu interfaz. Ordenar no cambia ninguno; eliminar p1 deja una línea y una unidad. Calcula estas cifras desde estado, sin mantener un segundo contador que pueda divergir.

Cuatro respuestas comprobables: ancho280/padding24/gap12/dos columnas→122; ADD desde [] devuelve un nuevo array manteniendo el anterior vacío; nombre en blanco con email válido y postal02001 produce solo error de nombre; cantidades2/1 producen tres unidades. Context puede actualizar consumidores por cambios de su valor aunque estén memorizados, así que «solo renderiza el componente afectado» no es una garantía. FlatList usa una ventana de renderización y puede incluir elementos fuera de lo visible, no exactamente solo filas en pantalla. Registra estado inicial, evento y salida por caso; un render correcto no demuestra persistencia.

Cuatro comprobaciones de accesibilidad: imagen con texto alternativo, foco de teclado, formulario etiquetado y estructura HTML semántica.
CursaloMapa de práctica
Accesibilidad: cuatro comprobaciones

El texto alternativo comunica el propósito de una imagen. La navegación por teclado necesita un foco visible; los campos necesitan etiquetas y la página una estructura semántica. Estas comprobaciones ayudan a detectar barreras y no sustituyen una auditoría completa.

Ver la infografía en tamaño completo ↗

Tipo de lección: Quiz

Concepto clave

En React Native con Expo, la gestión de estado y la interfaz de usuario avanzada trabajan juntas como el cerebro y los músculos de una app. Imagina que estás construyendo un dashboard financiero: el estado (como el saldo actual o las transacciones recientes) es la información que cambia, mientras que la UI (botones, gráficos, listas) es cómo el usuario interactúa con esa información. Sin una gestión de estado eficiente, tu UI se vuelve lenta o inconsistente, similar a un cajero automático que muestra saldos incorrectos.

Para apps intermedias, necesitas ir más allá del estado local de componentes. Herramientas como Context API o Redux Toolkit te permiten compartir estado entre múltiples pantallas, manteniendo la UI sincronizada. Piensa en esto como un sistema centralizado de notificaciones en un edificio: cuando algo cambia (como un nuevo mensaje), todas las pantallas relevantes se actualizan automáticamente, sin necesidad de pasar datos manualmente entre componentes.

Cómo funciona en la práctica

Vamos a implementar un carrito de compras en una app de e-commerce. Primero, define el estado global usando Context API. Crea un archivo CartContext.js que almacene los items del carrito y funciones para agregar o eliminar productos. Luego, envuelve tu app con este contexto en App.js, permitiendo que cualquier componente acceda al carrito.

En la UI, usa componentes optimizados como FlatList para mostrar los items del carrito eficientemente, incluso con cientos de productos. Para interacciones, implementa botones que despachen acciones al contexto (ej., "agregar al carrito"), lo que actualizará el estado y re-renderizará solo los componentes afectados. Esto evita recargas completas de la pantalla, mejorando el rendimiento en dispositivos móviles.

Código en acción

Antes: Estado local en un componente, difícil de compartir.

import React, { useState } from 'react';
import { View, Text, Button } from 'react-native';

const ProductScreen = () => {
  const [cart, setCart] = useState([]);
  
  const addToCart = (product) => {
    setCart([...cart, product]);
  };
  
  return (
    
      Producto: Camiseta
      
  );
};

export default ProductScreen;

Después: Estado global con Context API, fácil de acceder desde cualquier pantalla.

import React, { createContext, useContext, useReducer } from 'react';
import { View, Text, Button } from 'react-native';

const CartContext = createContext();

const cartReducer = (state, action) => {
  switch (action.type) {
    case 'ADD_ITEM':
      return { ...state, items: [...state.items, action.payload] };
    case 'REMOVE_ITEM':
      return { ...state, items: state.items.filter(item => item.id !== action.payload) };
    default:
      return state;
  }
};

const CartProvider = ({ children }) => {
  const [state, dispatch] = useReducer(cartReducer, { items: [] });
  
  return (
    
      {children}
    
  );
};

const ProductScreen = () => {
  const { dispatch } = useContext(CartContext);
  
  const addToCart = () => {
    dispatch({ type: 'ADD_ITEM', payload: { id: 1, name: 'Camiseta', price: 20 } });
  };
  
  return (
    
      Producto: Camiseta
      
    
  );
};

export { CartProvider, ProductScreen };

Errores comunes

  • Actualizar estado directamente: Modificar el estado sin usar setState o dispatches causa bugs. Siempre usa funciones inmutables.
  • No optimizar listas largas: Usar ScrollView para listas con muchos items ralentiza la app. Cambia a FlatList con keyExtractor.
  • Contextos anidados innecesariamente: Crear múltiples contextos para datos relacionados complica el código. Combina estados en un solo contexto cuando sea lógico.
  • Olvidar limpiar suscripciones: En efectos (useEffect), no remover listeners o intervalos puede causar fugas de memoria. Usa funciones de limpieza.
  • Ignorar el rendimiento en UI compleja: Componentes que se re-renderizan frecuentemente sin necesidad. Usa React.memo o useMemo para evitar cálculos costosos.

Checklist de dominio

  1. ¿Puedes crear un contexto global que maneje estado compartido entre al menos 3 pantallas?
  2. ¿Implementas listas eficientes con FlatList y propiedades como initialNumToRender?
  3. ¿Usas reducers o estado local según la complejidad del componente?
  4. ¿Manejas estados de carga y error en la UI para mejorar la experiencia del usuario?
  5. ¿Optimizas re-renders con técnicas como useCallback para funciones pasadas a hijos?
  6. ¿Integras gestos táctiles (ej., PanResponder) con actualizaciones de estado?
  7. ¿Pruebas la UI en ambos iOS y Android usando Expo Go para verificar consistencia?

Implementa un sistema de favoritos con estado global y UI optimizada

En este ejercicio, construirás una funcionalidad de favoritos para una app de recetas. Sigue estos pasos:

  1. Crea un nuevo proyecto Expo usando npx create-expo-app RecipeFavorites.
  2. Define un contexto FavoritesContext que almacene un array de IDs de recetas favoritas. Incluye acciones para agregar y quitar favoritos.
  3. Envuelve tu App con FavoritesProvider en App.js.
  4. Crea una pantalla RecipeListScreen que muestre una lista de al menos 5 recetas (usa datos mock). Cada item debe tener un botón de "Favorito" que cambie de estado al presionarlo.
  5. Implementa la lista con FlatList, asegurándote de usar keyExtractor y propiedades de rendimiento como windowSize.
  6. Añade una pantalla FavoritesScreen que muestre solo las recetas favoritas, accediendo al contexto global.
  7. Prueba la app en Expo Go: verifica que al marcar/desmarcar favoritos, ambas pantallas se actualicen inmediatamente.
Pistas
  • Usa useReducer en el contexto para manejar acciones de manera predecible.
  • Para el botón de favorito, cambia el ícono (ej., corazón vacío/lleno) basado en si el ID está en el array de favoritos.
  • Si la lista de recetas es estática, considera usar useMemo para evitar re-crear datos en cada render.

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.