Saltar al contenido

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

Quiz: Evaluación de gestión de estado y arquitectura

Tipo de lección: QuizConcepto claveLa gestión de estado avanzada en aplicaciones Expo implica coordinar múltiples fuentes de datos y mantener la consistencia en aplicaciones complejas. Piensa en esto como dirigir una orquesta.

Del concepto a la práctica

Taller de esta lección

La evaluación final del módulo exige asignar cada dato a una sola responsabilidad. El criterio no es usar más bibliotecas, sino evitar duplicación y conservar una ruta clara desde la acción hasta la pantalla.

Ejemplo resuelto

Para una tarea se decide: título y estado confirmado pertenecen a la caché de servidor; el filtro pertenece a Zustand; una modificación sin conexión pertenece a SQLite con pending; TaskRow recibe datos y callbacks. Si el usuario completa t1 offline, se actualiza la fila local y se encola el cambio, pero no se marca la consulta remota como confirmada.

Pruébalo

  1. Clasifica cinco campos: filtro, título, error de red, fila pendiente y selección.

  2. Dibuja el flujo de completar una tarea offline.

  3. Señala dónde se produce la confirmación.

  4. Identifica una duplicación y elimínala.

Error frecuente: usar un estado global para representar simultáneamente “pendiente de enviar” y “confirmado”. Corrígelo con estados separados y transiciones explícitas.

Comprueba tu resultado

La solución debe asignar cada campo a una capa, mostrar la transición offline y explicar que la confirmación remota ocurre después del envío exitoso.

Diagrama de decisión con ramas Sí y No y un bucle que procesa cada elemento de una lista.
CursaloMapa de práctica
Cómo avanza un programa

Una condición decide qué camino ejecuta el programa. Un bucle repite una operación mientras queden elementos, y termina cuando la lista se agota. Separar ambas ideas ayuda a seguir el flujo y comprobar casos límite.

Ver la infografía en tamaño completo ↗

Tipo de lección: Quiz

Concepto clave

La gestión de estado avanzada en aplicaciones Expo implica coordinar múltiples fuentes de datos y mantener la consistencia en aplicaciones complejas. Piensa en esto como dirigir una orquesta sinfónica: cada instrumento (componente) debe tocar en armonía, siguiendo la partitura (estado global), mientras el director (gestor de estado) asegura que todos estén sincronizados. En aplicaciones reales, esto significa manejar datos del servidor, caché local, preferencias del usuario y estado de UI simultáneamente.

La arquitectura escalable se refiere a diseñar tu aplicación de manera que pueda crecer sin volverse inmanejable. Imagina construir un rascacielos: necesitas cimientos sólidos (patrones de arquitectura), sistemas modulares (separación de responsabilidades) y planes de expansión (rutas de actualización claras). En Expo, esto se traduce en estructurar tu proyecto para que nuevos desarrolladores puedan entenderlo rápidamente y nuevas funcionalidades puedan añadirse sin romper lo existente.

Cómo funciona en la práctica

Vamos a implementar un sistema de gestión de estado para una aplicación de comercio electrónico con Expo. Primero, definimos nuestras necesidades: productos (datos del servidor), carrito (estado local persistente), usuario (autenticación) y preferencias (configuración). Usaremos Redux Toolkit para el estado global y Context API para estados más específicos.

Paso 1: Configura la estructura de carpetas. Crea src/store/ para Redux, src/contexts/ para Context API, y src/hooks/ para hooks personalizados. Paso 2: Define los slices de Redux para productos y carrito. Paso 3: Crea contextos para autenticación y tema. Paso 4: Implementa hooks personalizados para acceder fácilmente a estos estados desde cualquier componente.

Código en acción

Antes: Estado desorganizado en componentes individuales

// ProductScreen.js - ANTES
import React, { useState, useEffect } from 'react';
import { View, Text } from 'react-native';

export default function ProductScreen({ route }) {
  const [product, setProduct] = useState(null);
  const [loading, setLoading] = useState(true);
  const [cart, setCart] = useState([]);
  
  useEffect(() => {
    fetchProduct(route.params.id).then(data => {
      setProduct(data);
      setLoading(false);
    });
  }, []);
  
  const addToCart = () => {
    setCart([...cart, product]);
    // Problema: este estado no persiste entre pantallas
  };
  
  if (loading) return Cargando...;
  return (
    
      {product.name}
      
    
  );
}

Después: Estado centralizado con Redux Toolkit

// store/cartSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import AsyncStorage from '@react-native-async-storage/async-storage';

export const fetchCart = createAsyncThunk(
  'cart/fetchCart',
  async () => {
    const cartData = await AsyncStorage.getItem('cart');
    return cartData ? JSON.parse(cartData) : [];
  }
);

const cartSlice = createSlice({
  name: 'cart',
  initialState: {
    items: [],
    status: 'idle',
  },
  reducers: {
    addItem: (state, action) => {
      state.items.push(action.payload);
      AsyncStorage.setItem('cart', JSON.stringify(state.items));
    },
    removeItem: (state, action) => {
      state.items = state.items.filter(item => item.id !== action.payload);
      AsyncStorage.setItem('cart', JSON.stringify(state.items));
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchCart.pending, (state) => {
        state.status = 'loading';
      })
      .addCase(fetchCart.fulfilled, (state, action) => {
        state.status = 'succeeded';
        state.items = action.payload;
      });
  },
});

export const { addItem, removeItem } = cartSlice.actions;
export default cartSlice.reducer;

Errores comunes

  • SOBRECARGA DE REDUX: Usar Redux para todo, incluso estado local de componentes. Solución: Usa useState para estado que solo afecta a un componente, Context para estado compartido en un árbol pequeño, y Redux solo para estado verdaderamente global.
  • MUTACION DIRECTA DEL ESTADO: Modificar arrays u objetos directamente en Redux. Solución: Siempre usa inmutabilidad, con spread operators o funciones como map/filter.
  • FALTA DE NORMALIZACION: Almacenar datos anidados que causan duplicación. Solución: Normaliza tus datos como lo harías en una base de datos, usando IDs como referencias.
  • IGNORAR EL RENDIMIENTO: No memoizar selectores en componentes que se rerenderizan frecuentemente. Solución: Usa createSelector de Redux Toolkit o useMemo para cálculos costosos.
  • ACOPLAMIENTO EXCESIVO: Componentes que conocen demasiado sobre la estructura del estado. Solución: Usa hooks personalizados como abstracción entre componentes y lógica de estado.

Checklist de dominio

  1. ¿Puedes explicar la diferencia entre estado local, contexto y estado global?
  2. ¿Implementaste persistencia de estado con AsyncStorage o similar?
  3. ¿Normalizaste datos complejos para evitar duplicación?
  4. ¿Usaste selectores memoizados para optimizar rendimiento?
  5. ¿Estructuraste tu store de Redux con slices separados por dominio?
  6. ¿Creaste hooks personalizados para abstraer la lógica de estado?
  7. ¿Documentaste las decisiones de arquitectura para tu equipo?

Refactorización de una aplicación Expo con gestión de estado avanzada

Refactoriza una aplicación existente de lista de tareas para usar una arquitectura escalable. La aplicación actual tiene todo el estado en componentes individuales y no escala bien.

  1. Analiza la aplicación base: Descarga el proyecto inicial desde el repositorio proporcionado. Identifica todos los lugares donde se maneja estado.
  2. Diseña la arquitectura: Crea un diagrama que muestre cómo organizarás el estado. Decide qué va a Redux (estado global), qué a Context API (estado compartido limitado), y qué se queda como estado local.
  3. Implementa Redux Toolkit: Configura el store con slices para tareas y filtros. Incluye persistencia con AsyncStorage.
  4. Crea contextos: Implementa un contexto para el tema (claro/oscuro) y otro para preferencias de usuario.
  5. Desarrolla hooks personalizados: Crea al menos 2 hooks como useTasks y useTheme que abstraigan el acceso al estado.
  6. Refactoriza componentes: Actualiza todos los componentes para usar la nueva arquitectura, manteniendo la misma funcionalidad.
  7. Prueba la escalabilidad: Añade una nueva funcionalidad (como categorías de tareas) demostrando cómo se integra fácilmente en tu arquitectura.
Pistas
  • Comienza por identificar qué datos son verdaderamente globales vs locales
  • Usa Redux DevTools para depurar el flujo de estado durante la refactorización
  • Considera usar normalización para las tareas si tienen relaciones complejas

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.

Sigue con Desarrollo Avanzado de Aplicaciones con Expo: De Concepto a Producción

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.