Cómo integrar Redux en su aplicación con React Native y Expo

Redux es una parte importante del ecosistema React Native. Si su mundo gira en torno a JavaScript, probablemente haya oído hablar de Redux. Antes de leer el resto del tutorial y continuar, solo intenta recordar que solo estás aprendiendo sobre Redux porque te facilitará las cosas, y no más. Ahora aprendamos por qué necesita Redux en su aplicación.

Necesidad de Redux

La creación de una aplicación React o React Native en el mundo real puede volverse compleja si no existe una forma adecuada de manejar los datos. Si en algún momento no se gestionan los datos, las cosas se saldrán de control. Si está familiarizado con React o React Native, sabe que la forma predeterminada de manejar los datos es mantenerlos en un estado de componente y pasarlos a los componentes secundarios como accesorios.

State y Props son las únicas dos formas de controlar los datos de un componente. Props es la abreviatura de propiedades. Es una regla simple a seguir en el mundo de React que no debemos mutar o cambiar el valor de los accesorios. En React, el flujo de datos es unidireccional o unidireccional. Es decir, los datos siempre se pueden pasar de un componente principal a un componente secundario. Eche un vistazo a continuación a este sencillo ejemplo:

En el ejemplo anterior, creamos dos componentes (padre e hijo) en archivos separados. El componente principal consta de una vista en la que se representa el componente secundario. En el componente secundario, la vista muestra un mensaje de texto que proviene de los accesorios. El mensaje entrante está disponible como datos en el estado del componente principal.

De esta manera, el componente secundario se puede reutilizar con otros componentes principales, de modo que cada componente principal puede tener sus propios datos para representar. Tenga en cuenta que no estamos modificando el valor de this.propsen ningún momento.

El estado está ahí para mutar datos. Ésta es la única razón por la que el estado existe dentro de cada componente. Siempre que queremos cambiar el estado, usamos el this.setState()método dentro de un componente. Este método vuelve a representar el componente y todos sus componentes secundarios para reflejar los cambios. Esto funciona tanto en React como en React Native de manera similar, pero los aspectos internos son diferentes.

Dado que podemos administrar el estado y los accesorios de manera tan eficiente dentro de una aplicación React Native, ¿por qué es necesario Redux? Bueno, el ejemplo anterior representa lo mínimo y no un escenario en tiempo real. Imagina una aplicación como Instagram o Twitter. Tiene diferentes pantallas, y cada pantalla puede depender de uno o dos componentes, como los componentes padre e hijo reutilizables de nuestro ejemplo. Sería difícil realizar un seguimiento del estado de cada componente.

Redux es una de las formas de manejo de datos más ampliamente adoptadas. Permite que el estado se comparta como un atributo global que una aplicación React Native completa puede usar y recibir en forma de accesorios. Esto se conoce como crear una tienda en Redux. Redux simplifica el estado moviéndolo a un solo lugar.

Redux usa un mecanismo de reacción subyacente llamado contexto. No vamos a detenernos en lo que es el contexto, ya que está fuera del alcance de este artículo. Solo quería que supieras que no ocurre nada mágico detrás de escena.

Solo recuerda los siguientes términos, ya que los veremos en acción en el tutorial a continuación:

  • Comportamiento
  • Reductores
  • Tienda

La clave para aprender Redux es la práctica. No quiero compartir demasiada información y abrumar las cosas en este momento. Así que comencemos creando una aplicación de demostración para aprender Redux.

Construyendo una aplicación Pomodoro

¿Empezando con Expo-CLI?

Para construir esta aplicación, voy a utilizar la última herramienta presentada por el equipo de la Expo llamada expo-cli. Instálelo como una dependencia global y luego inicialice un nuevo proyecto React Native usándolo.

Para ver si todo funciona correctamente en este estado inicial, ejecute el siguiente comando.

Se le solicitará la siguiente interfaz. Tómate un tiempo para revisarlo. Si ha creado aplicaciones con Expo XDE o Create-React-Native-App antes, verá que no ha cambiado mucho, excepto que ahora Expo-CLI hace uso del navegador Chrome.

Elija un simulador o dispositivo que pueda ejecutar Expo Client como se indica en la imagen de arriba. Si aparece la siguiente pantalla, significa que nuestro proyecto React Native se ha inicializado sin dificultades.

Con eso, cree los siguientes archivos y carpetas dentro del componentsdirectorio. Discutiré por qué seguimos esta estructura de directorio más adelante. Por ahora, nuestra configuración inicial está completa y podemos comenzar a construir nuestra aplicación.

Componente del temporizador ⏱

Primero, crearemos un componente Timer tonto y lo conectaremos con App.js. Agregue el siguiente código al Timer/index.js:

A continuación, modifique el App.jsarchivo:

Ahora crearemos un componente Timer estático para ver cómo encajan las cosas. Comenzaremos modificando el StatusBar. Luego definimos dos Textelementos de la react-nativebiblioteca para especificar dónde se mostrará el temporizador real y dónde se mostrarán los botones para iniciar y detener el temporizador. Por ahora, ambos son campos de texto.

¿Añadiendo botones?

En esta sección, reemplazaremos la sección que se muestra Start and Stop Buttons!con botones reales. Usaremos TouchableOpactiypara que esto funcione. Un TouchableOpacitycomponente actúa como un contenedor para hacer que las vistas respondan correctamente a los toques. La opacidad de la vista envuelta (o el botón en nuestro caso) disminuye cada vez que un usuario lo toca.

Creamos un componente reutilizable ya que necesitamos dos botones: Iniciar y Detener.

Este es un componente sin estado, por lo que no tiene clase; solo lo necesitamos para representar el botón en la interfaz de usuario de nuestra aplicación. También importamos íconos de FontAwesome @expo/vector-icons, que es una bifurcación de react-native-vector-icons y viene directamente con expo SDK. No es necesario instalarlo como una dependencia separada. Para mostrar un icono, necesitamos definir su size.

Por último, en el componente sin estado anterior, definimos propTypes. Discutiré cómo y por qué deberíamos usar PropTypes en una aplicación React Native en otro artículo.

En una aplicación móvil, los eventos se activan al tocar. Para manejar esos eventos, usaremos onPress. Tendremos solo dos eventos aquí, Start y Stop. Ambos botones de nuestra aplicación van a hacer uso de lo onPressOutque difiere de onPress. El onPressOutse llama cada vez que el usuario suelta el toque (cuando el usuario deja de presionar el botón). Se llama antes onPressy es más preciso en una situación como la nuestra donde necesitamos iniciar o detener el temporizador presionando el botón tan pronto como el usuario haya terminado.

Ahora necesitaremos este Buttoncomponente en nuestro componente Timer.

¿Integrando Redux?

Hasta ahora, nuestra aplicación Timer no hace nada más que mostrar una interfaz de usuario mínima. Para que funcione, comenzamos agregando algunas dependencias necesarias de Redux.

Ahora, comencemos a integrar Redux en nuestra aplicación.

Acciones?

En Redux, el estado de toda la aplicación está representado por un objeto JavaScript. Piense en este objeto como de solo lectura, ya que no podemos realizar cambios en este estado (que se representa en forma de árbol) directamente. Necesitamos actionshacerlo.

Las acciones son como eventos en Redux. Pueden activarse en forma de clics del mouse, pulsaciones de teclas, temporizadores o solicitudes de red. La naturaleza de cada evento mencionado es mutable. Una acción es un objeto JavaScript. Para definir una acción, hay un requisito: cada acción tiene su propia propiedad de tipo. Definimos estos tipos en un archivo llamado types.js:

Nuestra aplicación solo necesita tres acciones hasta ahora. El tipo de cualquier acción es un valor de cadena y se define como una constante.

En el archivo actions.js, necesitaremos estos tipos para definir los creadores de acciones. Los creadores de acciones son funciones que crean acciones.

Reductores

El receptor de la acción se conoce como reductor. Siempre que se activa una acción, el estado de la aplicación cambia. El manejo del estado de la aplicación lo realizan los reductores.

Un reductor es una función pura que calcula el siguiente estado en función del estado inicial o anterior. Siempre produce la misma salida si el estado no cambia. Se necesitan dos entradas, y el estado y la acción deben devolver el estado predeterminado.

En nuestro estado inicial, definimos tres atributos: isPlaying, elapsedTimey timerDuration. El temporizador actualmente tiene un valor predeterminado de 6 (segundos) para fines de prueba, pero el valor real que cambiaremos más adelante es 25(o 1500 segundos).

Entonces hay tres funciones auxiliares:

  • applyStartTimer iniciará el temporizador
  • applyRestartTimer detendrá la función del temporizador y configurará todo a los valores predeterminados
  • y por último, applyAddSecondcomprobará si el tiempo transcurrido es menor que la duración total del temporizador. Si es así, agregará un segundo más para aumentar su valor. De lo contrario, devolverá el estado predeterminado y detendrá la función del temporizador.

Después de eso, definimos nuestra función reductora y exportamos la misma función. Observe cómo se organiza la función reductora. Este es un patrón seguido por la mayoría de los miembros de la comunidad que he visto en Internet.

Este es un buen recurso para comenzar con Redux en general por Dan Abramov y ¡es GRATIS!

¿Creando Redux Store?

Con la ayuda del reductor y el estado inicial, podemos crear el objeto de tienda.

Una tienda es un objeto que reúne acciones y reductores. Proporciona y mantiene el estado a nivel de aplicación en lugar de componentes individuales. Redux no es una biblioteca obstinada en términos de qué marco o biblioteca debería usarla o no.

Para vincular una aplicación React o React Native con Redux, hágalo con react-reduxmodule. Esto se hace utilizando el componente de orden superior Provider. Básicamente, pasa la tienda al resto de la aplicación.

Necesitamos vincular a los creadores de acciones con nuestra función de temporizador para que sea completamente funcional (para que responda a los eventos táctiles o al inicio o reinicio del temporizador). Haremos esto en la Timer/index.jsfunción.

Primero, importamos las dependencias necesarias para vincular a los creadores de acciones.

bindActionCreatorsmapea funciones de acción a un objeto usando los nombres de las funciones de acción. Estas funciones envían automáticamente la acción a la tienda cuando se llama a la función. Para cambiar los datos, necesitamos enviar una acción. Para habilitar esto, necesitamos dos cosas: mapStateToPropsy mapDispatchToProps, y necesitamos conectar ambas con nuestro componente. Este es el código repetitivo que volverá a escribir.

Definimos estas dos funciones y modificamos nuestra export defaultdeclaración después de definir los estilos para nuestras vistas React Native.

mapStateToPropses un objeto que vive en la tienda cuyas claves se pasan al componente como accesorios. El siguiente es el código completo para el componente Timer.

Completando la aplicación ⚛️ +?

He creado una función personalizada llamada formatTimepara mostrar la hora en el formato correcto, pero puede hacer uso de cualquier biblioteca de temporizadores. A continuación, para incrementar el valor del tiempo, utilizo el método del ciclo de vida React componentWillReceiveProps. Sé que pronto se desaprobará, pero por ahora funciona. Vea nuestra mini-aplicación en acción a continuación:

En aras de la brevedad y esta demostración, estoy usando solo segundos para mostrar el temporizador. Puede aumentar el valor del temporizador editando el valor de constante TIMER_DURATIONen reducers.js.

Hemos llegado al final del artículo. Con suerte, te has divertido tanto leyéndolo como yo escribiéndolo. Puede encontrar el código completo para este artículo en este repositorio de Github:

amandeepmittal / rn-pomodoro-example

rn-pomodoro-example - React Native + Redux integaration github.com

¿Recuerda que le conté acerca de una estructura de archivo en particular que seguí al implementar la arquitectura Redux? Bueno, se llama patrón de re-patos y puedes encontrar más detalles en este artículo informativo de Alex Moldovan:

Escalando su aplicación Redux con patos

¿Cómo se escala su aplicación front-end? ¿Cómo se asegura de que el código que está escribiendo se pueda mantener durante 6 meses? Medium.freecodecamp.org

? Para más preguntas, contácteme en Twitter o lea más sobre mí en mi sitio web.

Si desea recibir actualizaciones sobre mi próximo artículo sobre React Native, considere suscribirse a mi boletín.