REDUX con Angular
¿Qué es REDUX?
Seguramente es una palabra que has visto en tu incursión a la programación reactiva y sus patrones de diseño. Sin más, REDUX es una librería de JavaScript que, a grandes rasgos, es el contenedor del estado de tu aplicación. Y decimos contenedor por que básicamente la información de toda tu aplicación se concentra en un solo lugar llamado Store. Este patrón no es exclusivo de un framework, ya que podemos implementarlo en aplicaciones hechas en React, Vue, Angular o JavaScript puro.
El patrón REDUX nos permite saber:
- ¿Cuál es el estado de mi aplicación en este momento?
- ¿Qué valor tiene determinada variable?
- ¿Quién cambió esa variable o alguna otra variable?
- ¿Cómo cambió la información, en qué momento y otra información relacionada al estado de la aplicación?
Los principios de REDUX
Redux se basa en 3 ideas principales
- Solo Existe una fuente de verdad: Esto nos quiere decir que, toda la data de la información se encuentra en una estructura previamente definida, antes que hagamos la mutación de la información sabemos de antemano que se almacenará en la misma y toda la información se encontrará almacenada en un único lugar llamado STORE. El STORE ¡jamás! se modifica de forma directa.
- El estado es de solo lectura: El estado(State) de nuestra aplicación representa el valor actual de la misma. La única manera de modificar el estado de nuestra aplicación será por medio de acciones, ya que las acciones son objetos planos pueden ser registrados, serializados y almacenados para volver a ejecutarlos por cuestiones de depuración y pruebas.
- Los cambios se realizan con funciones puras: Prácticamente este principio nos dice qué, un nuevo estado es creado con base en un estado anterior y una acción, y devuelven un nuevo estado. Todo este flujo está descrito por una función llamada Reducer.
NgRx
Es el estándar de facto para implementar Redux en Angular. Está basada en RxJS y es una librería modular con todo lo necesario para crear grandes aplicaciones. Esto son los módulos que la componen.
Un estándar de facto es aquel patrón o norma que se caracteriza por no haber sido consensuada ni legitimada por un organismo de estandarización al efecto.
State
Este elemento es la clave de toda la organización de datos. Aquí es donde se almacenan los datos para nuestra aplicación. Normalmente el estado lo tendremos modularizado en distintos modelos, tales como un modelo Usuario o un modelo Rol, que reflejan los distintos modelos de datos que va a necesitar nuestra aplicación. En definitiva, es la información que vamos a mostrar al usuario de la aplicación web pero organizada en el Store.
Cabe destacar que siguiendo el paradigma de que el store es la única fuente de verdad, los componentes solo van a obtener la información de este State y no podrán recibirla de ningún otro sitio, ya que dejaríamos de aplicar REDUX si lo hiciéramos.
Action
Siguiendo la implementación, para realizar cualquier cosa, un componente va siempre a desencadenar una acción. Ya sea solicitar un listado de usuarios o la modificación de un registro, el componente lo que hará será simplemente notificar al Store que quiere llevar a cabo esa acción despachando esta Action y, a partir de ahí, el Store se encargará de realizar las operaciones que sean necesarias para llevarla a cabo y crear una nueva versión del estado de la aplicación.
Estas actions podríamos considerarlas los mensajeros que envían el componente al Store para especificar qué quiere hacer.
Tiene 2 propiedades:
- type: Nos describe la acción a realizar y es un parámetro obligatorio. Se busca que las acciones sean lo más simples posibles.
- payload: Es la información adicional para la acción, este parámetro es opcional.
Reducer
En este punto es importante recordar que el estado de nuestra aplicación es inmutable. Esto implica que cuando cambia algún dato, en realidad lo que hacemos es sustituir el estado por uno nuevo que incorpora los cambios.
Debido a esto, existen los reducers. Son funciones puras cuya única función es sustituir el estado de la aplicación antiguo por un estado nuevo con los cambios que se hayan introducido.
Los reducers son además el único elemento autorizado a modificar el estado de la aplicación, son el único canal por el que podemos sustituir un estado previo por el nuevo estado.
Un ejemplo:
Effect
Un aspecto importante que hemos mencionado de pasada es que los reducers son funciones puras, por lo que no pueden hacer nada que no sea tomar como argumento el estado previo e incluir los cambios en el nuevo estado que estamos creando.
Esta aproximación nos deja varias situaciones que no podemos controlar bien, como el hecho de que el cambio que debemos hacer en el Store dependa de la respuesta que obtenemos del servidor, un caso muy común por otra parte. Esto no puede hacerlo un reducer, un reducer no puede tomar decisiones de este tipo.
Aquí es donde los effects pueden ayudarnos. Un effect es una función asociada a un Action que nos ayudará a realizar todas aquellas tareas auxiliares que necesitemos. Este elemento nos da una gran flexibilidad a la hora de gestionar nuestro flujo de datos.
Fijándonos en el esquema del flujo de NgRx, los effects son los encargados de gestionar la comunicación con los servicios de nuestra app, siendo, a su vez, los elementos que gestionan la comunicación con las distintas fuentes de datos.
Demo Crud:
https://github.com/gamunax/Angular-9-CRUD-with-Redux