Sincronización del estado global y logout limpio

En las clases anteriores ya hemos creado un estado global compartido entre distintas partes de la aplicación. Funciona, pero ahora empezamos a notar comportamientos raros: componentes que se vuelven a renderizar cuando no deberían, estados que no se actualizan como esperamos o inconsistencias al cerrar sesión.

En esta clase vamos a profundizar en cómo sincronizar correctamente el estado global entre diferentes páginas, optimizar las suscripciones para reducir renders innecesarios y dejar preparado un logout limpio, sin estados zombis ni UI desactualizada.

El problema: renders innecesarios

Uno de los primeros síntomas es ver que un componente se vuelve a renderizar aunque no esté usando la parte del estado que ha cambiado.

Esto suele pasar cuando hacemos algo como:

const store = useStore()

De esta forma nos estamos suscribiendo a toda la store, aunque luego solo usemos una pequeña parte de ella.

Consecuencia

  • Cada cambio en cualquier parte del estado provoca un rerender.
  • Componentes que no deberían actualizarse, se actualizan.

Suscribirse solo a lo que importa

Para mejorar el rendimiento, lo ideal es suscribirse únicamente a las partes del estado que realmente necesitamos.

Por ejemplo, si un botón solo necesita saber:

  • si un item es favorito
  • y la acción para alternarlo

Podemos extraer solo eso:

const isFavorite = useStore((state) => state.isFavorite)
const toggleFavorite = useStore((state) => state.toggleFavorite)

Esto reduce renders y hace que cada componente dependa solo de lo que usa.

El efecto secundario: cuando no se re-renderiza

Al hacer esto, aparece un nuevo problema interesante.

Si una acción no cambia su referencia y el estado al que estamos suscritos no varía, React no vuelve a renderizar el componente. Y eso es correcto.

El problema surge cuando:

  • Cambia una lista global (por ejemplo, favoritos)
  • Pero el componente no está suscrito a esa lista

Resultado

  • El estado global cambia.
  • Pero el componente no se entera.

Aquí aprendemos una lección clave:

Suscribirse poco es bueno, pero suscribirse a lo incorrecto rompe la sincronización.

Suscribirse al estado correcto

Si un componente necesita reaccionar cuando cambia la lista de favoritos, debe suscribirse a ella, aunque solo use una parte.

No es un problema suscribirse a más estado si:

  • Tiene sentido semántico.
  • Es necesario para reflejar cambios en la UI.

El objetivo no es minimizar suscripciones a toda costa, sino hacerlas coherentes.

Estado global compartido entre páginas

Una vez bien suscritos los componentes:

  • El listado de ofertas
  • El detalle de una oferta
  • Los botones de favoritos

Todos quedan sincronizados.

Puedes marcar un favorito en el listado, entrar al detalle y ver el mismo estado. Quitar el favorito en el detalle y volver atrás, y el listado se actualiza correctamente.

Esto confirma que:

  • El estado global se comparte.
  • Los renders ocurren solo donde tiene sentido.

React Router y renders

Es normal observar que algunos Link se re-renderizan al navegar. Esto suele estar más relacionado con React Router que con nuestro estado global.

Lo importante es que:

  • Los botones
  • Los estados visuales
  • Las acciones

solo se re-rendericen cuando deben.

Logout limpio: resetear la UI correctamente

El último paso es manejar bien el cierre de sesión.

Al hacer logout:

  • El estado global sigue existiendo.
  • Pero la UI debe reaccionar correctamente.

Para ello:

  • Leemos el estado de login desde la store.
  • Desactivamos botones si el usuario no está autenticado.
  • Evitamos acciones como aplicar a una oferta o marcar favoritos sin sesión.
const isLogged = useAuthStore((state) => state.isLogged)

Y a partir de ahí:

  • Desactivar botones.
  • Evitar efectos secundarios.
  • Mantener la UI consistente.

Qué te llevas de esta clase

  • Cómo evitar renders innecesarios en un estado global.
  • Por qué suscribirse solo a lo que necesitas no siempre es suficiente.
  • Cómo sincronizar estado entre distintas páginas.
  • Cómo preparar la aplicación para un logout limpio.
  • Cómo pensar en estado global más allá de “que funcione”.

En la siguiente clase seguiremos afinando el diseño del estado global y viendo patrones para escalarlo sin romper rendimiento ni claridad mental.