React Redux y TypeScript

React Redux y TypeScript

En los últimos años, el desarrollo front-end ha pasado por una verdadera revolución, impulsada por tecnologías innovadoras y enfoques eficientes, siendo dos de ellas Redux y TypeScript. Mientras que Redux es una biblioteca que permite la creación de interfaces interactivas y escalables, TypeScript es un lenguaje de programación que añade características de tipado estático a JavaScript, permitiendo la detección de errores durante la fase de desarrollo y mejorando la calidad y robustez del código.

La combinación de Redux y TypeScript ha demostrado ser extremadamente valiosa para el front-end, ofreciendo una experiencia de programación más agradable, reduciendo errores y aumentando la eficiencia. Dada la importancia de ambos, hoy aprenderemos a implementar Redux en TypeScript, desarrollando una aplicación que tendrá todo lo necesario para ello.

¿Qué es React?

React es una biblioteca de JavaScript de código abierto utilizada por diversas empresas notables como Facebook, Netflix, Instagram, etc. Centrada en crear interfaces de usuario de manera mucho más práctica que usando JavaScript puro, React ha ido ganando cada vez más terreno por ser fácil de aprender, comprender y adaptar.

¿Qué es un estado?

Es muy importante, antes de empezar a trabajar, entender el concepto de estado y para qué sirve. Imagina que tienes una aplicación que, al realizarse un tipo de interacción (como, por ejemplo, añadir un artículo al carrito o aplicar un filtro para limitar lo que quieres ver), necesita que cierta cantidad de información se guarde temporalmente, con el objetivo de que otros componentes o rutas tengan acceso a ella mientras la pantalla no se cierre o actualice. Ese pequeño lugar donde se almacena esta información es lo que llamamos estado. Sin él, todo en React sería un caos o, al menos, diez veces más difícil de implementar.

Primeros Pasos

Para entender la mecánica principal de una implementación de Redux en TypeScript, crearemos una aplicación React con dos rutas, donde una de ellas tendrá un catálogo de artículos (la llamaremos "Home") y la otra mostrará los que el usuario haya elegido (la llamaremos "ShoppingCart"). Para esto, necesitamos crear un proyecto React, instalar el administrador de rutas (react-router-dom) y, finalmente, TypeScript. Para ello, ejecuta la siguiente secuencia de códigos en una terminal abierta en el directorio donde desees que se almacene tu proyecto:

npx create-react-app shopping-cart
cd shopping-cart
npm i react-router-dom
npm install react-redux
npm install @reduxjs/toolkit
npm install -D typescript@4.9.5
npx tsc --init

Después de la ejecución, elimina los archivos innecesarios generados por "create-react-app" y cambia los archivos “App.js” e “index.js” al formato “.tsx”. Con todas las implementaciones necesarias para crear las rutas que utilizaremos, tu código debería verse similar al mostrado a continuación:

Figura 1 - Implementación del archivo index.tsx com con el componente “BrowserRouter” y tipificación de la constante “root”
Figura 2 - Implementación de “app.tsx” con la creación de las rutas “home” y “shopping-cart”
Figura 3 - Componente Home
Figura 4 - Componente ShoppingCart
Figura 5 - Componente “tsconfig.json”

¡Estamos casi listos para empezar a implementar Redux! Falta poblar el componente Home con algunos artículos que podrán ser seleccionados y guardados en el estado que crearemos. Utilizaremos uno de los endpoints de la API de Mercado Libre para esto:

Figura 6 - Función que extrae datos de una API y los guarda en un estado

En la figura 6, utilizamos la función “fetchItems” para acceder a un endpoint de la API y registrar en el estado “list” una lista de artículos. En las figuras siguientes (Figuras 7 y 8) realizaremos la implementación que accederá a estos datos y los mostrará en la pantalla. Notarás que el método de estilización utilizado es Tailwind, que usa el modelo de atomic CSS, donde cada clase tiene una única función, como por ejemplo transformar el estilo de un texto a cursiva o alinearlo a la derecha. Puedes estilizar tu aplicación como prefieras, ya que nuestro objetivo va más allá.

Figura 7 - Función que extrae datos de una API y los guarda en un estado
Figura 8 - Función que extrae datos de una API y los guarda en un estado

Para cada artículo (recorremos cada uno de ellos a través del “map” utilizado en la línea 52 de la Figura 7), tendremos una imagen, un título, el enlace para acceder al artículo en Mercado Libre (líneas 55, 62 y 63 de la figura 7, respectivamente), el precio y un botón (líneas 65 y 68 de la figura 8), aún sin funcionalidad asignada, que en el futuro usaremos para insertar el artículo en el estado global creado a través de Redux.

Figura 9 - Ejecución en el navegador del componente Home

Configurando o Redux

Ahora que a nuestra aplicación prácticamente solo le falta la implementación de Redux, ha llegado el momento de instalar los paquetes necesarios para ello. Ejecuta el siguiente código en una terminal iniciada en la carpeta raíz de tu proyecto:

npm i react-redux @reduxjs/toolkit

Comenzaremos creando un directorio llamado redux, donde dentro crearemos dos archivos con extensión “.ts”, llamados “store” y “slice”.

Redux Toolkit tiene una función llamada “createSlice”, que se utilizará principalmente para describir acciones en el estado global de la aplicación, como insertar, actualizar y eliminar datos. El “createSlice" recibe como parámetros un objeto con tres campos:

  • “name” - recibe una cadena que se utilizará como identificador;
  • “initialState” - contiene el estado global inicial, es decir, cuando inicializamos la aplicación;
  • “reducers” - debe contener un objeto con las funciones que realizan acciones en el estado global (por ahora, como se puede ver en la figura 10, este campo estará vacío porque solo estamos implementando la estructura básica. Más adelante, cuando insertemos datos en el estado global, crearemos estas funciones juntos).
Figura 10 - Implementación del Slice

Nota que realizamos dos exportaciones en el archivo “slice.ts”. Una de ellas (línea 13 de la figura 10), la exportación por defecto, la utilizaremos en el store y la otra (línea 15 de la figura 10) la usaremos para acceder a la información contenida en Redux.

Implementando el archivo “store.ts”. Mientras que en “slice.ts” realizamos todas las actividades relacionadas con la manipulación del estado global, en el “store” crearemos el almacenamiento. Utilizamos la función “configureStore” para esto, pasando como parámetro un objeto que tiene una clave llamada “reducer”. Esta clave tendrá como valor un objeto que contendrá todos los “reducers” que tengamos en nuestra aplicación (en nuestro caso, solo hemos creado uno llamado slice, exportado en la línea 13 de la figura 10, por lo que crearemos un único conjunto clave-valor):

Figura 11 - Implementación del Store

Insertando datos en Redux

Para manipular el estado global generado con Redux, utilizamos el hook ”useDispatch”. Es muy sencillo de usar: le pasas como parámetro una función (que será una acción creada en el “reducer”) y esta función realizará algún tipo de cambio en el estado global.

Para ejemplificar, asignaremos el uso de este hook a los botones de agregar que creamos para cada artículo en la página “Home”. Primero, crearemos una función en el reducer que recibe como parámetro un objeto y lo agrega a una lista:

Figura 12 - Creación de la función addFavorite

Nota que las funciones que utilizamos como argumento de la clave “reducers” (línea 16 de la figura 12) reciben dos parámetros: un estado, representado por state y equivalente al estado actual de la aplicación (añadido directamente por Redux), y una action, que es un objeto que tiene las claves “type” y “payload”. Como se puede ver en la línea 17 de la figura 12, estamos utilizando solo el payload desestructurado, ya que es en esta clave donde se pasan los parámetros que usamos en la aplicación.

Finalmente, importaremos “useDispatch” en nuestra página Home y lo asignaremos al botón de cada artículo, pasando como parámetro la función “addFavorites”, que a su vez tendrá como parámetro el contenido del artículo en cuestión:

Figura 13 - Importación del Hook “useDispatch” (y asignación a una constante) y la función “addFavorite”
Figura 14 - Implementación de “useDispatch” (línea 74)

Por último, necesitamos conectar el store (el almacenamiento del estado global) a nuestra aplicación. En la función “index.tsx” utilizaremos el componente Provider, que tendrá una propiedad llamada "store" que recibirá como valor el “store” que recibirá como valor el “store” que creamos:

Figura 15 - Creación del Provider (línea 12)

¡Ahora ya estamos guardando datos en el estado global creado con Redux! Pero, ¿cómo acceder a estos datos? ¡Lo veremos ahora!

Accediendo a los datos de Redux

Mientras que “useDispatch” inserta, modifica o elimina datos del estado global, el hook responsable de acceder a estos datos es “useSelector”. Este recibe como parámetro la función “useSlice” que creamos en la línea 15 de la figura 10. Después de asignar “useSelector” a una constante, el proceso es bastante sencillo: accedemos a la clave “list” dentro del estado y mapeamos la lista contenida en ella, creando un componente para cada elemento:

Figura 16 - Importación e implementación de “useSelector” (líneas 3 y 6)
Figura 17 - Mapeo de la lista contenida dentro del estado global de redux
Figura 18 - Aplicación en ejecución

Consideraciones finales

En el artículo de hoy aprendimos a utilizar React Redux dentro del lenguaje TypeScript, desglosando todas las implementaciones necesarias para ello. ¡Recuerda que tener la documentación a la mano es extremadamente importante cuando estamos aprendiendo nuevos lenguajes, frameworks o bibliotecas!

Si te pareció interesante este artículo, si tienes alguna duda o simplemente te gustaría platicar sobre estos y otros temas, también puedes ponerte en contacto conmigo a través del correo bruno.cabral.silva2018@gmail.com o ¡en mi perfil de LinkedIn!

¡Te espero con ansias!

💡
Las opiniones y comentarios emitidos en este artículo son propiedad única de su autor y no necesariamente representan el punto de vista de Listopro.

Listopro Community da la bienvenida a todas las razas, etnias, nacionalidades, credos, géneros, orientaciones, puntos de vista e ideologías, siempre y cuando promuevan la diversidad, la equidad, la inclusión y el crecimiento profesional de los profesionales en tecnología.