0:0012:07

Recursos

Resumen

Si estás construyendo una app de hábitos en React y necesitas conectar tu estado global con el almacenamiento local, aquí aprenderás a crear un provider usando useReducer y useEffect para hidratar y guardar información de forma automática. Es ideal para quien ya domina context y quiere persistir datos reales.

La idea central es sencilla: pasar toda la información desde el centro de mando hacia el provider, que actúa como el proveedor de datos para toda la aplicación. Y para lograrlo, combinamos tres piezas de React que trabajan juntas.

Qué hace el provider dentro del context de React

El provider es la pieza que nos permite proveernos del estado que guardamos por detrás. Retorna un React Node, porque justamente devuelve un componente proveedor que envuelve a la aplicación.

Dentro del context definimos un type que agrupa tres cosas: los hábitos, la carga de estos (el loading) y las funcionalidades. Con eso creamos la variable del context usando la función de crear context, y ahí vive toda la central de mandos [00:26].

Cuando no tenemos ese tipo disponible, la respuesta por defecto es entregar un null. Esa es la salida en cualquier caso donde el estado no exista todavía.

¿Qué es un provider en React? Es un componente que envuelve tu aplicación y distribuye el estado global a todos los componentes hijos. Devuelve un React Node y conecta el context con los datos que guardas por detrás.

Cómo funciona useReducer para manejar el estado de hábitos

useReducer es el corazón del manejo de estado en este provider. Lo creamos para tener un estado y una funcionalidad al mismo tiempo [01:08].

Lo que hace es entregarte dos cosas:

  • El state, con la actualización de ese mismo estado.
  • El dispatch, la funcionalidad que se ejecuta sobre ese estado.

Para ponerlo en marcha, nos traemos el reducer y el initialState. Así el useReducer queda inicializado con un punto de partida claro y una lógica centralizada para actualizar los hábitos.

Después del useReducer viene la parte donde React empieza a hablar con la memoria de la app, y ahí entra el useEffect.

Cómo hidratar datos desde el async storage con useEffect

El primer useEffect hace una validación antes de cualquier movimiento: revisa cómo está nuestro listado de hábitos al arrancar [01:32]. Esto se llama hidratación.

Dentro usamos una función asíncrona con try catch para un buen manejo de errores. Los pasos son estos:

  • Usar await para esperar al async storage, que es la memoria de la aplicación [01:53].
  • Traer el ítem guardado mediante nuestra key, que en este caso es el storageKey.
  • Parsear esa información con JSON, convirtiéndola de texto almacenado al tipo hábito.
  • Ejecutar el dispatch con una funcionalidad de tipo hidratar, enviando como payload la información ya parseada.

Si no existe estado guardado, entramos al else y retornamos un dispatch vacío, porque no hay nada que cargar. Y si algo falla, el catch lanza un console.warn con el mensaje "No se pudo cargar hábitos" para detectar y solucionar el error [02:56].

¿Para qué sirve el async storage en React Native? Es la memoria persistente de la aplicación. Guarda datos como texto usando una key, y los recuperas con await para que sobrevivan aunque cierres la app.

Un detalle técnico: el async storage viene de una librería específica que se instaló en la clase anterior, y se importa con el from correspondiente.

Cómo guardar hábitos automáticamente al agregar uno nuevo

Aquí viene lo interesante: el segundo useEffect se encarga de guardar los hábitos cada vez que agregamos uno nuevo [04:20].

Primero creamos un saveTimer, una referencia de guardado que puede ser null o un timeout. Esto lo importamos como un hook de React para controlar el tiempo de guardado.

El flujo del guardado funciona así:

  1. Verificar el state: si está cargando (loading en true), no retornamos nada todavía.
  2. Limpiar el timer anterior con clearTimeout, para iniciar desde cero.
  3. Dentro de un try catch asíncrono, usar await con el storage y agregar el ítem.
  4. Entregar la llave de almacenamiento y la data convertida con JSON.stringify, porque el storage recibe la data en formato JSON.

Si el guardado falla, un console.warn con "No se pudo guardar" nos deja la pista fechada del problema [06:07]. Y cuando todo termina, limpiamos de nuevo el saveTimer con clearTimeout.

Es clave que este useEffect escuche los cambios del estado: ponemos state de hábitos y state.loading como dependencias, para que reaccione tanto al listado como a su carga [06:40].

Qué funcionalidades expone el provider

Para cerrar, el provider entrega dos funcionalidades esenciales a través del dispatch: agregar y seleccionar hábitos [06:58].

Estas acciones son las que conectan todo lo que ya existe en el context con lo que el usuario hará en pantalla. Con esto ya tienes la base del proveedor lista para implementarse.

¿Vas a probar este patrón de hidratación y guardado en tu propia app? Cuéntame en los comentarios cómo te fue.

Provider con useReducer y useEffect para hábitos

Ver clases