Lorenzo GM

Reflexiones sobre desarrollo web, ingeniería de software y prácticas tecnológicas modernas

English|Spanish
Lorenzo GM

Mejores Prácticas de Gestión de Estado Frontend

Pensamientos personales sobre estrategias efectivas de gestión de estado frontend - priorizando estado URL, cookies y minimizando el estado de React

Front-EndState ManagementBest Practices
Mejores Prácticas de Gestión de Estado Frontend

Mejores Prácticas de Gestión de Estado Frontend

La gestión de estado es uno de los aspectos más críticos del desarrollo frontend, pero a menudo se complica demasiado. Después de años de experiencia construyendo aplicaciones web complejas, he desarrollado algunos pensamientos con opinión sobre cómo abordar la gestión de estado de manera efectiva.

La Jerarquía de Gestión de Estado

Al decidir dónde almacenar el estado en tu aplicación frontend, recomiendo seguir este orden de prioridad:

1. Siempre Trata de Usar la URL Primero

La URL debería ser tu fuente principal de verdad para el estado de la aplicación siempre que sea posible. Este enfoque ofrece varios beneficios clave:

  • Compartibilidad: Los usuarios pueden marcar y compartir estados específicos de la aplicación
  • Navegación del navegador: Los botones atrás/adelante funcionan intuitivamente
  • Beneficios SEO: Los motores de búsqueda pueden indexar diferentes estados de tu aplicación
  • Depuración: El estado actual siempre es visible en la barra de direcciones
  • Persistencia: El estado sobrevive a las actualizaciones de página sin complejidad adicional
// Bueno: Usando parámetros URL para filtros
const searchParams = useSearchParams();
const category = searchParams.get('category') || 'all';
const sortBy = searchParams.get('sort') || 'name';

// Malo: Almacenar los mismos datos en estado de React
const [category, setCategory] = useState('all');
const [sortBy, setSortBy] = useState('name');

2. Cookie de Sesión Única como Respaldo

Cuando el estado URL no es práctico (datos sensibles, demasiados datos, o consideraciones de UX), usa una sola cookie de sesión manejada apropiadamente en el frontend:

  • Una cookie de sesión: Evita múltiples cookies que necesiten sincronización
  • Manejo apropiado: Asegúrate de que el frontend pueda leer y actualizar la sesión apropiadamente
  • Expiración clara: Establece tiempos de expiración razonables
  • Seguridad: Usa flags HttpOnly y Secure cuando sea apropiado
// Bueno: Sesión única con datos estructurados
const session = {
  userId: '123',
  preferences: { theme: 'dark', language: 'en' },
  cart: { items: [], total: 0 }
};

// Malo: Múltiples cookies separadas
// userIdCookie, themePreferenceCookie, cartCookie, etc.

3. Evita Múltiples Cookies

Múltiples cookies crean pesadillas de sincronización:

  • Complejidad de sincronización: Mantener múltiples cookies sincronizadas es propenso a errores
  • Rendimiento: Múltiples cabeceras HTTP en cada solicitud
  • Dificultad de depuración: Estado disperso en múltiples ubicaciones de almacenamiento
  • Condiciones de carrera: Las actualizaciones a diferentes cookies pueden crear estados inconsistentes

4. El Estado de React Debería Ser la Excepción

Context API, useState, y otra gestión de estado de React deberían usarse con moderación:

  • Solo estado UI local: Inputs de formulario, visibilidad de modal, estados de carga
  • Interacciones temporales: Estados hover, gestión de foco, animaciones
  • Estado derivado: Cálculos basados en props u otro estado
// Bueno: Estado UI local
const [isModalOpen, setIsModalOpen] = useState(false);
const [isLoading, setIsLoading] = useState(false);

// Malo: Estado de aplicación que debería estar en URL o sesión
const [currentUser, setCurrentUser] = useState(null);
const [shoppingCart, setShoppingCart] = useState([]);

Por Qué Importa Esta Jerarquía

Reducción de Complejidad

Al seguir esta jerarquía, minimizas el número de fuentes de estado en tu aplicación. Cada fuente de estado adicional aumenta exponencialmente la complejidad:

  • 1 fuente: Simple
  • 2 fuentes: Necesita sincronización
  • 3+ fuentes: Gestión de estado compleja con conflictos potenciales

Depuración y Desarrollo

Cuando el estado está principalmente en la URL y una sesión única:

  • Depuración más fácil: El estado es visible y manipulable
  • Mejor testing: Estados reproducibles a través de manipulación de URL
  • Incorporación más simple: Los nuevos desarrolladores pueden entender el flujo de estado rápidamente

Experiencia de Usuario

  • Comportamiento predecible: Los usuarios entienden cómo funcionan los navegadores
  • Mejor rendimiento: Menos sobrecarga de gestión de estado JavaScript
  • Accesibilidad: Los lectores de pantalla y otras herramientas funcionan mejor con navegación basada en URL

Estrategias de Implementación

Gestión de Estado URL

// Hook personalizado para estado URL
function useURLState(key, defaultValue) {
  const searchParams = useSearchParams();
  const router = useRouter();
  
  const value = searchParams.get(key) || defaultValue;
  
  const setValue = useCallback((newValue) => {
    const params = new URLSearchParams(searchParams);
    if (newValue === defaultValue) {
      params.delete(key);
    } else {
      params.set(key, newValue);
    }
    router.push(`?${params.toString()}`);
  }, [key, defaultValue, searchParams, router]);
  
  return [value, setValue];
}

Gestión de Sesión

// Gestión de sesión centralizada
class SessionManager {
  private static readonly SESSION_KEY = 'app_session';
  
  static getSession() {
    try {
      const session = document.cookie
        .split('; ')
        .find(row => row.startsWith(this.SESSION_KEY))
        ?.split('=')[1];
      return session ? JSON.parse(decodeURIComponent(session)) : null;
    } catch {
      return null;
    }
  }
  
  static updateSession(updates) {
    const current = this.getSession() || {};
    const updated = { ...current, ...updates };
    document.cookie = `${this.SESSION_KEY}=${encodeURIComponent(JSON.stringify(updated))}; path=/; max-age=86400`;
  }
}

Errores Comunes a Evitar

Sobre-ingeniería de Gestión de Estado

No recurras a librerías complejas de gestión de estado (Redux, Zustand, etc.) a menos que hayas agotado opciones más simples:

// A menudo innecesario
const useGlobalStore = create((set) => ({
  user: null,
  setUser: (user) => set({ user }),
  // ... cientos de líneas de lógica de estado
}));

// Usualmente suficiente
const user = SessionManager.getSession()?.user;

Optimización Prematura

No optimices la gestión de estado antes de tener una comprensión clara de tus necesidades reales de estado:

  • Comienza con URL y sesión
  • Añade estado de React solo cuando sea necesario
  • Mide el rendimiento antes de añadir complejidad

Conclusión

La gestión efectiva de estado frontend no se trata de usar las herramientas más sofisticadas—se trata de elegir la herramienta correcta para cada pieza de estado. Al priorizar el estado URL, usar una sesión única bien gestionada, y tratar el estado de React como la excepción en lugar de la regla, construirás aplicaciones que son más fáciles de desarrollar, depurar y mantener.

Recuerda: la mejor solución de gestión de estado es la más simple que cumple tus requisitos. Comienza simple y añade complejidad solo cuando sea absolutamente necesario.


Créditos de imagen: OpenReplay Blog - React State Management with Easy Peasy