Uso de Mobx como administrador de estado en aplicaciones nativas de React

Publicado: 2022-03-10
Resumen rápido ↬ MobX es una de las muchas herramientas de administración de estado disponibles para los desarrolladores de React. En este tutorial, Fortune Kay explica qué es MobX y cómo puede usarlo en sus aplicaciones React creando una desde cero.

La gestión del estado es una parte integral del desarrollo de aplicaciones JavaScript, especialmente las aplicaciones React y React Native. En este tutorial, vamos a aprender a usar la biblioteca MobX para la gestión del estado; comprender los conceptos básicos, algunos casos de uso y construir un ejemplo simple.

Nota: El conocimiento básico de Javascript y React Native será de gran beneficio a medida que avanza en este tutorial.

Uso de MobX en aplicaciones React

El estado son los datos con los que están trabajando sus componentes: contiene los datos que requiere un componente y dicta lo que representa un componente. La gestión de estado es el proceso de gestionar cómo se actualiza y pasa el estado de un componente a otro. Supervisar y trabajar con datos en una aplicación puede ser difícil y esa es la necesidad de bibliotecas de administración de estado. Manejar todos los datos para su aplicación puede ser un poco desalentador, especialmente cuando su aplicación crece en tamaño y complejidad, crear su propia herramienta de administración de estado no solo requiere mucho tiempo sino que también es difícil. Es por eso que es posible que desee utilizar una biblioteca de administración de estado.

Sin embargo, es importante saber que el estado no es el único dato que representa un componente, los componentes también pueden representar accesorios que se le transmiten.

Opciones para la gestión del estado

Las bibliotecas de administración de estado para aplicaciones React Native incluyen; React Context API, Redux, MobX y Unstated Next.

Aunque cada uno de estos administradores estatales tiene sus ventajas y desventajas, personalmente recomiendo MobX debido a su simplicidad, código repetitivo mínimo: no requiere que cambie su código, esto se debe a que, en esencia, MobX es y se parece a JavaScript; no necesita un cambio de arquitectura para admitirlo (a diferencia de Redux y, en menor medida, Context).

De hecho, es una abstracción tan invisible que, en muchos casos, si elimina todo el código MobX : los decoradores @observable , @computed , @action y Observer, su código funcionará exactamente igual (aunque tendrá algunos problemas de rendimiento). ) y no se limita a un estado global. Estas son algunas de las razones para seguir adelante con MobX como administrador de estado elegido para sus aplicaciones React Native.

Aunque también es importante tener en cuenta algunos problemas con el uso de MobX como administrador de estado, algunos de los cuales incluyen evitar las reglas sobre cómo implementarlo y MobX puede ser difícil de depurar, especialmente cuando cambia el estado directamente en un componente sin usar @actions parámetro.

¿Qué es MobX?

De acuerdo con la documentación oficial, MobX es una biblioteca probada en batalla que hace que la administración del estado sea simple y escalable mediante la aplicación transparente de programación reactiva funcional. MobX trata su aplicación como una hoja de cálculo. La lógica es que todo lo que se pueda derivar del estado de la aplicación, debe hacerse automáticamente .

Arquitectura de estado MobX
Arquitectura estatal MobX. (Vista previa grande)
¡Más después del salto! Continúe leyendo a continuación ↓

Principios básicos y concepto de MobX

MobX se diferencia de otros gestores estatales con los siguientes conceptos.

1. Estado

El estado son los datos que contiene su aplicación; es aproximadamente todo el contenido de su memoria. Esto también se aplica a sus componentes.

2. Derivaciones

En MobX, cualquier cosa que pueda derivarse del estado sin interacciones es una derivación. Ejemplos de derivaciones incluyen:

  • Interfaz de usuario,
  • Complementos de back-end, como cambios en un servidor.

MobX tiene dos tipos principales de derivaciones:

  • Valores calculados
    Los valores calculados son en su mayoría valores que se pueden derivar de un estado actual usando funciones puras.
  • reacciones
    Las reacciones en las derivaciones son efectos secundarios que ocurren como resultado de cambios en el estado de su aplicación. Son similares a un valor calculado, pero en lugar de producir un nuevo valor, una reacción produce un efecto secundario para cosas como imprimir en la consola, realizar solicitudes de red, actualizar gradualmente el árbol de componentes de React para parchear el DOM, etc.

Una regla de oro al usar MobX es que al crear un valor basado en el estado actual, use un valor calculado.

3. Acciones

A diferencia de las derivaciones, las acciones son código que provocan cambios en el estado de una aplicación, código que cambia el estado. Son cualquier cosa que modifica el estado. Con MobX, puede hacerlo explícito en su código. Las acciones son en su mayoría eventos de usuario, como entradas, envíos de datos de back-end o incluso eventos programados.

Para comprender mejor las acciones, veamos un ejemplo de la documentación de MobX.

 class Ticker { @observable tick = 0 @action increment() { this.tick++ // 'this' will always be correct } } const ticker = new Ticker() setInterval(ticker.increment, 1000)

Aquí, configuramos un tic @observable con un valor inicial de 0. Luego, creamos un incremento de función que también es una acción que actualiza el valor inicial una vez que se realiza un tic cada segundo.

Observables en MobX

Los observables o los valores observables en MobX son en su mayoría primitivos de JavaScript, objetos simples, clases, matrices y mapas. Se utilizan principalmente al declarar primero un observable y agregarle un valor y luego llamarlo agregando un @observable como se muestra a continuación:

 observable(value) @observable classProperty = value

Enfoque de la arquitectura de la tienda en MobX

La arquitectura principal de MobX incluye partes e ideas como servicios, tiendas, modelos de visualización y contenedores, algunos de los cuales se explican a continuación.

  • Servicio
    Esta suele ser una función llamada desde un contenedor; se pueden usar para obtener datos de las API y agregarse a la tienda.
  • Tienda
    Como su nombre lo indica, este es el lugar central del estado utilizado por una aplicación. Por lo general, en MobX, estos incluyen los observables, las variables, las acciones y las propiedades calculadas.
  • Envase
    Esto llama service y coloca los datos de View Model en View Component como accesorios de React (debe marcarse con el decorador @observer ).

MobX en React y aplicaciones nativas

Con fines de aprendizaje, en este tutorial, vamos a crear una aplicación de lista simple que permitirá al usuario agregar, ver y eliminar elementos de la lista. Usaremos MobX como administrador de estado en esta aplicación para agregar listas, actualizarlas y eliminarlas del estado de la aplicación. Sin embargo, es importante tener en cuenta que ya comprende los conceptos básicos de JavaScript y React.

Sin más preámbulos, ¡comencemos!

Configuración de su entorno

Ahora que sabemos qué es MobX y cómo funciona, déjame guiarte en la configuración de tu proyecto.

Primero, creemos un proyecto con lo siguiente, escriba el siguiente código en su terminal para inicializar un proyecto:

 npx create-react-app listapp

El código anterior creará una aplicación React simple utilizando el paquete create-react-app. Mover al directorio del proyecto:

 cd listapp

Para esta aplicación, necesitaremos tres componentes:

  • TitleInput
    Esto contendrá el título de nuestro proyecto y un formulario de entrada para agregar listas.
  • List
    Este será un formulario de entrada que permitiría a un usuario agregar una lista. Tendrá un botón Agregar para agregar nuestros elementos de lista.
  • ListsDisplay
    Este componente mostrará todos los elementos de la lista de usuarios y también un botón de eliminación que se genera automáticamente cuando un usuario agrega un elemento de la lista.

Usaremos un Store.js para contener el estado de la aplicación y los métodos para modificarlo de manera similar a Redux. Vamos a esbozar para qué se utilizarán.

  • mobx
    Este es el administrador de estado que usaremos para este proyecto.
  • mobx-react
    Estos son los enlaces oficiales de React para MobX.
  • bootstrap
    Usaremos la versión 4.5 de bootstrap para diseñar nuestro proyecto.
  • uuid
    Esto se usa para crear automáticamente claves para eliminar listas.

Habiendo hecho eso, sigamos adelante e instalemos estos paquetes. Los instalaré con una alternativa npm hecha en hilo:

 yarn add mobx mobx-react [email protected] uuid

Una vez que los paquetes estén instalados, iniciaremos nuestra aplicación en modo de desarrollo ejecutando el siguiente código en nuestra terminal:

 yarn start

Configuración de nuestra tienda de aplicaciones

Vamos a crear una tienda para nuestro proyecto. Primero, cree un archivo en el directorio raíz de nuestro proyecto llamado ListStore , esta será la ubicación central del estado de nuestra aplicación.

Para esta aplicación, necesitaremos crear un ListStore para no repetirnos cuando lo usamos en otros componentes de la aplicación.

 /*** src/Store.js ***/ import { observable, action, computed } from "mobx"; import { v4 } from "uuid"; export class List { @observable value @observable done constructor (value) { this.id = v4() this.value = value } } export class ListStore { @observable lists = [] @observable filter = "" @action addList = (value) => { this.lists.push(new List(value)) } @action deleteList = (list) => { this.lists = this.lists.filter(t => t !== list) } @computed get filteredLists () { const matchCase = new RegExp(this.filter, "i") return this.lists.filter(list=> !this.filter || matchCase.test(list.value)) } }

En el código anterior, importamos tres funciones de mobx .

  • observable
    Contiene una variable que se puede actualizar en caso de un cambio de estado.
  • action
    Se utiliza para modificar el estado de la aplicación.
  • computed
    Los valores que se pueden derivar del estado existente u otros valores calculados, cambian después de que se modifica un estado.

La clase List tiene dos valores de objeto que están done y un value que mantendrá el estado inicial de la aplicación y la modificación en caso de cambios.

Queremos que nuestra nueva lista cree automáticamente una clave para que podamos obtener automáticamente un botón de eliminación una vez que se crea una lista. Aquí, uuid se usa para crear claves automáticamente en nuestra aplicación.

Luego, agregamos una función addList que agregará listas cuando se haga clic usando el método .push() para insertar la lista en la matriz que ya creamos en la @observable lists .

La función deleteList acepta List como una propiedad que se supone que es el elemento que el usuario desea eliminar. Luego establecemos el valor de this.Lists en una nueva matriz después de haber eliminado el elemento seleccionado.

Tanto addLists como deleteList son acciones porque modifican el estado de nuestra aplicación cuando se realizan cambios.

Inicializar la tienda MobX

Lo siguiente en nuestra lista es importar nuestra tienda en nuestro App.js y usarla en nuestro proyecto.

 import React from 'react'; import Navbar from "./components/navbar"; import ListDisplay from "./components/ListDisplay"; import {ListStore} from './ListStore'; function App() { const store = new ListStore() return ( <div> <Navbar store={store}/> <ListDisplay store={store}/> </div> ); } export default App;

Aquí importamos los componentes TitleInput y ListDisplay . Luego inicializamos la tienda en nuestro App.js para poder pasarla como accesorios a los componentes TitleInput y ListDisplay .

Normalmente, esto generará un error porque no hemos trabajado en los otros componentes, así que hagámoslo. Construyamos el componente ListDisplay .

ListDisplay

Este componente muestra todas nuestras listas agregadas y también genera automáticamente un botón de eliminación una vez que se agrega una nueva lista.

 import React from 'react' import List from "./List"; import { observer } from 'mobx-react'; function ListDisplay(props) { const { deleteList, filteredLists } = props.store return ( <div> <div className="container"> {filteredLists.map(list => ( <List key={list.id} list={list} deleteList={deleteList} /> ))} </div> </div> ) } export default observer(ListDisplay)

Para este componente, creamos una función ListDisplay y la convertimos en un observador, también desestructuramos las funciones list y deletelist de la tienda, al hacer esto, facilitamos el paso como accesorios de objetos.

A continuación, mapeamos a través de listas filteredLists para devolver las listas, que luego usamos para crear la lista individual al pasar el elemento devuelto como accesorios al componente List .

Una vez hecho esto, nuestro componente debería verse así con las listas agregadas:

El componente de visualización de lista
Listas mostradas por el componente `ListDisplay`. (Vista previa grande)

Lo siguiente es agregar los componentes List y TitleInput .

Componente de lista

Al igual que nuestros otros componentes, nuestro componente List exportará la lista como un observador para ayudar a la tienda a observar los cambios.

 import React from 'react' import { observer } from 'mobx-react' function List(props) { return ( <div className="card"> <div className="card-body"> <div className="d-flex justify-content-between align-items-center"> <p className={`title ${props.list.done ? "text-secondary" : ""}`}> {props.list.value} </p> <div> <button onClick={props.deleteList.bind(this, props.list)} className="btn btn-danger font-weight-bold py-2 px-5 ml-2"> Delete </button> </div> </div> </div> </div> ) } export default observer(List)

Usé el arranque para crear tarjetas en el primer conjunto de divs y también alineé el ícono de eliminar para moverlo hacia el lado derecho de la aplicación. Primero, creamos un componente de tarjeta para manejar nuestra list y luego creamos una etiqueta de botón para el button Eliminar que aceptará dos objetos de este y pasará un apoyo a la lista, esto al hacer clic eliminará el elemento de lista seleccionado de la listas en la página.

El componente de la lista
Un único componente de lista con el botón Eliminar. (Vista previa grande)

El siguiente es nuestro TitleInput que contendrá nuestro formulario de entrada para agregar listas y el título del proyecto.

TitleInput

De manera similar a nuestros otros proyectos, agregaremos una función @observer para que el componente pueda aceptar accesorios de la tienda de aplicaciones.

 import React, { useState } from 'react' import { observer } from 'mobx-react' function Navbar(props) { const [value, setValue] = useState("") const {addList} = props.store const prepareAddList = (e) => { e.preventDefault() addList(value) setValue("") } return ( <div className="container mt-3"> <h1 className="title">List App</h1> <form onSubmit={prepareAddList} className="form-group"> <div className="row ml-lg-2"> <input className="form-control-lg col-12 col-lg-9 col-sm-12 mr-3 border border-secondary" value={value} type="text" onChange={(e) => setValue(e.target.value)} placeholder="Enter list" /> <button className="col-lg-2 col-5 col-sm-5 mt-2 mt-lg-0 mt-sm-2 btn btn-lg btn-success font-weight-bold"> Add to List </button> </div> </form> </div> ) } export default observer(Navbar)

Primero, inicializamos un estado inicial. Usando React Hooks, agregamos un estado inicial llamado values que configuramos en una cadena vacía. Usamos esto para mantener el valor de lo que se ingresa en el campo de entrada. Para saber más sobre React Hooks, puede consultar este artículo de David Abiodun.

Luego llamamos a un objeto para agregar listas a la tienda addList y lo pasamos como accesorios de la tienda de aplicaciones.

A continuación, creamos una función preparedAddList para aceptar un objeto de evento para los formularios de entrada, también agregamos un botón para agregar las listas manualmente al hacer clic.

Casi terminado, necesitamos reiniciar nuestro servidor de proyectos ejecutando:

 yarn start

Y nuestro TitleInput debería verse así:

Una entrada de título
Título y componente de entrada. (Vista previa grande)

Ya hemos terminado con todos los componentes de nuestra aplicación, así que vamos a montarlo en nuestro App.js Para hacer eso, necesitamos importar nuestros componentes titleInput y ListDisplay . También necesitamos importar nuestra tienda desde el componente Tienda.

Para que MobX funcione en nuestra aplicación, debemos pasar la tienda MobX como accesorios en nuestra aplicación y componentes individuales para que obtengan las propiedades y funciones en la tienda.

 import React from 'react'; import Navbar from "./components/navbar"; import ListDisplay from "./components/ListDisplay"; import {ListStore} from './ListStore'; function App() { const store = new ListStore() return ( <div> <Navbar store={store}/> <ListDisplay store={store}/> </div> ); } export default App;

Nuestra aplicación debería verse así cuando se complete:

Aplicación de lista completa
(Vista previa grande)

Conclusión

MobX es un excelente administrador de estado, especialmente para aplicaciones basadas en React, al construir nuestra aplicación de lista, hemos aprendido los conceptos básicos de MobX, estado, derivaciones y acciones. Una versión de trabajo de esta aplicación se puede encontrar aquí:

Puede llevar esto más lejos usando MobX en la próxima aplicación que cree que involucre la gestión del estado. Me encantaría ver qué cosas nuevas se te ocurren. Puede leer más sobre MobX y las aplicaciones de administración de estado en las referencias a continuación.

Recursos y referencias

  • “React Native con MobX — Primeros pasos”, Nader Dabit, Medium
  • “Conceptos y Principios” MobX (documentación oficial)
  • "Mejores prácticas con ganchos de reacción", Adeneye David Abiodun, Smashing Magazine