Objetivo del sistema

El objetivo principal era evitar que los datos de los héroes desaparecieran cada vez que el usuario recargaba la página.

Sin un sistema de persistencia, la aplicación siempre empezaría desde cero, perdiendo cualquier modificación realizada.

Por eso implementamos un flujo donde:

  1. La primera vez se cargan los datos iniciales.
  2. Se guardan en el navegador.
  3. En futuras visitas, se recuperan automáticamente.

Arquitectura de la solución

Para conseguir una solución limpia y escalable, se separó la lógica en dos partes:

1. Hook personalizado (useHeroes)

Se encarga de:

  • Gestionar el estado de la aplicación.
  • Decidir de dónde vienen los datos.
  • Conectar React con la lógica de almacenamiento.

2. Capa de almacenamiento (heroesStorage)

Se encarga de:

  • Leer datos desde localStorage.
  • Guardar datos en localStorage.
  • Cargar datos iniciales desde el JSON.
  • Validar la estructura de los datos.

Flujo completo de la aplicación

El comportamiento del sistema sigue este flujo:


1. Inicio de la aplicación

Cuando el usuario entra en la aplicación, se ejecuta el hook:

 
useHeroes()
 

Este hook es el punto central de toda la lógica.


2. Comprobación de datos en localStorage

Lo primero que hace la aplicación es comprobar si ya existen datos guardados:

 
getStoredHeroes()
 

Esta función intenta leer la clave:

 
heroes
 

del localStorage.


Caso A: existen datos

Si el usuario ya había usado la aplicación anteriormente:

  • Se recuperan los héroes guardados.
  • Se convierten de JSON a objetos JavaScript.
  • Se cargan directamente en el estado de React.

Resultado:

✔ La aplicación mantiene los datos anteriores
✔ No se pierden cambios del usuario
✔ La experiencia es continua entre sesiones


Caso B: no existen datos

Si es la primera vez que el usuario entra:

  • No hay información en localStorage.
  • Se cargan los datos iniciales desde un archivo JSON.
getInitialHeroes()

Estos datos representan el estado base de la aplicación.


3. Generación de identificadores únicos

Durante la carga inicial, a cada héroe se le asigna un identificador único:

 
id: Date.now() + index
 

Esto es necesario porque:

  • React necesita una clave única para renderizar listas.
  • Permite identificar cada héroe de forma individual.
  • Evita conflictos entre elementos.

4. Guardado en localStorage

Una vez generados los datos iniciales:

  • Se convierten a formato JSON.
  • Se almacenan en el navegador.
 
setStoredHeroes(initial)
 

Esto garantiza que:

✔ La próxima vez ya existan datos guardados
✔ No sea necesario volver a cargar el JSON
✔ La aplicación tenga persistencia


5. Actualización del estado en React

Finalmente, los datos se guardan en el estado:

 
setHeroes(initial)
 

Esto provoca que:

  • React vuelva a renderizar la interfaz.
  • Los héroes aparezcan en pantalla inmediatamente.

Rol del hook useHeroes

El hook useHeroes actúa como un intermediario entre:

  • La interfaz de usuario
  • El almacenamiento local
  • Los datos iniciales

Su función es simple pero muy importante:

Decidir de dónde vienen los datos y devolverlos listos para usar.


Ventajas de esta arquitectura

Esta solución mejora el proyecto en varios aspectos importantes:


1. Persistencia de datos

Los cambios del usuario no se pierden al recargar la página.


2. Separación de responsabilidades

Cada parte del sistema tiene una función clara:

  • Hook → lógica de React
  • Storage → manejo de datos
  • JSON → datos iniciales

3. Reutilización del código

Las funciones de heroesStorage pueden reutilizarse en otros hooks o componentes sin duplicar lógica.


4. Mayor seguridad

Se evita que la aplicación falle si los datos de localStorage están corruptos o mal formateados.


5. Código más limpio y mantenible

El hook deja de estar lleno de lógica compleja y se convierte en algo fácil de leer:

 
const storedHeroes = getStoredHeroes()

if (storedHeroes.length > 0) {
setHeroes(storedHeroes)
} else {
const initial = getInitialHeroes()
setStoredHeroes(initial)
setHeroes(initial)
}

 

Conclusión

Este sistema nos permite tener una aplicación:

  • Más robusta
  • Más escalable
  • Más fácil de mantener
  • Con persistencia de datos real en el navegador

 

💾 Preguntas sobre localStorage

 

  • ¿Qué es localStorage y en qué se diferencia de sessionStorage?
  • ¿Qué limitaciones tiene localStorage?
  • ¿Qué pasaría si el usuario borra los datos del navegador?
  • ¿Es seguro guardar datos en localStorage?
  • ¿Qué ocurre si localStorage está lleno?

💻 Código fuente

Todo el código está disponible en GitHub:  https://github.com/cjristian/table-marvel

 

Autor: Cristian Jiménez
Máster: Desarrollo Full Stack + Arquitecturas Cloud
Centro: Tajamar Tech
Año académico: 2025-2026
Recursos: https://github.com/cjristian/table-marvel

Leave a Comment

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.