Las mejores herramientas de gestión de estado de React para aplicaciones empresariales
Publicado: 2022-03-11Los desarrolladores de aplicaciones React de nivel empresarial saben lo crucial que es la gestión del estado para una experiencia de usuario final coherente.
Sin embargo, el usuario no es el único afectado por la gestión estatal. Los desarrolladores de React crean y mantienen el estado. Quieren que la gestión estatal sea simple, extensible y atómica. React se ha movido en esta dirección al introducir ganchos.
Pueden surgir problemas cuando el estado debe ser compartido entre muchos componentes. Los ingenieros deben encontrar herramientas y bibliotecas que se adapten a sus necesidades y, al mismo tiempo, cumplir con los altos estándares necesarios para las aplicaciones de nivel empresarial.
En este artículo, analizaré y compararé las bibliotecas más populares y elegiré la más adecuada para la gestión de estado en una aplicación de nivel empresarial.
Capacidades integradas de gestión de estado de reacción
React tiene una excelente herramienta para proporcionar datos a través de múltiples componentes. El objetivo principal de Context es evitar la perforación de puntales. Nuestro objetivo es obtener una herramienta fácil de usar para administrar el estado en varios escenarios que probablemente se encuentren en las aplicaciones empresariales: actualizaciones frecuentes, rediseños, la introducción de nuevas funciones, etc.
Si bien todo esto es teóricamente factible con Context, requeriría una solución personalizada que requiere tiempo para configurarse, brindar soporte y optimizarse. La única ventaja de Context es que no depende de una biblioteca de terceros, pero eso no compensa el esfuerzo por mantener este enfoque.
Además, el miembro del equipo de React, Sebastian Markbage, mencionó que la nueva API de contexto no se creó y optimizó para actualizaciones de alta frecuencia, sino para actualizaciones de baja frecuencia, como actualizaciones de temas y administración de autenticación.
Examen de bibliotecas existentes
Hay docenas de herramientas de administración de estado en GitHub (p. ej., Redux, MobX, Akita, Recoil y Zustand). Sin embargo, tomar cada uno de ellos en consideración llevaría a interminables investigaciones y comparaciones. Es por eso que reduje mi selección a los tres principales competidores en función de su popularidad , uso y mantenedor .
Para hacer explícita la comparación, utilizaré los siguientes atributos de calidad:
- usabilidad
- mantenibilidad
- Rendimiento
- Testabilidad
- Escalabilidad (funciona con el mismo rendimiento en los estados más grandes)
- modificabilidad
- Reutilización
- Ecosistema (tiene una variedad de herramientas auxiliares para ampliar la funcionalidad)
- Comunidad (tiene muchos usuarios y sus preguntas se responden en la web)
- Portabilidad (se puede usar con bibliotecas/marcos que no sean React)
redux
Redux es un contenedor estatal creado en 2015. Se hizo muy popular porque:
- No había una alternativa seria cuando se lanzó.
- Proporcionó la separación entre el estado y las acciones.
- La magia
react-reduxpermitió una conexión de estado directa. - El cocreador de la biblioteca es el aclamado desarrollador de Facebook y miembro del equipo central de React, Dan Abramov.
Tiene una tienda global donde residen sus datos. Cada vez que necesite actualizar la tienda, envía una acción que va al reductor . Dependiendo del tipo de acción, el reductor actualiza el estado de forma inmutable.
Para usar Redux con React, deberá suscribir los componentes a las actualizaciones de la tienda a través react-redux .
Ejemplo de API Redux
Las partes fundamentales de Redux en el código base que lo diferencia de las otras herramientas son los cortes. Contienen toda la lógica de acciones y reductores.
CódigoSandbox
// slices/counter.js import { createSlice } from "@reduxjs/toolkit"; export const slice = createSlice({ name: "counter", initialState: { value: 0 }, reducers: { increment: (state) => { state.value += 1; }, decrement: (state) => { state.value -= 1; } } }); export const actions = slice.actions; export const reducer = slice.reducer; // store.js import { configureStore } from "@reduxjs/toolkit"; import { reducer as counterReducer } from "./slices/counter"; export default configureStore({ reducer: { counter: counterReducer } }); // index.js import React from 'react' import ReactDOM from 'react-dom' import { Provider } from 'react-redux' import App from './App' import store from './store' ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') ) // App.js import React from "react"; import { useSelector, useDispatch } from "react-redux"; import { actions } from "./slices/counter"; const App = () => { const count = useSelector((state) => state.counter.value); const dispatch = useDispatch(); return ( <div> <div> <button onClick={() => dispatch(actions.increment())}>Increment</button> <span>{count}</span> <button onClick={() => dispatch(actions.decrement())}>Decrement</button> </div> </div> ); }; export default App;Atributos de calidad
- Usabilidad . Redux se volvió muy simple con la introducción del paquete de herramientas oficial. Creas un segmento (una combinación del estado inicial, los reductores y las acciones), lo pasas a la tienda y accedes a él en un componente a través de ganchos.
- Mantenibilidad . Redux es simple. No se requiere un conocimiento profundo para entender cómo mejorar o reparar algo.
- rendimiento El principal factor de influencia en el rendimiento con Redux es el ingeniero de software. Redux es una herramienta sencilla sin mucha lógica. Si ve que las actualizaciones de estado son lentas, puede seguir las pautas oficiales para acelerarlas.
- Testabilidad . Redux consta de funciones puras (acciones y reductores), lo que lo hace ideal para pruebas unitarias. También proporciona el mecanismo para escribir pruebas de integración donde la tienda, las acciones y los reductores trabajan juntos.
- Escalabilidad . De forma predeterminada, Redux tiene un estado global, lo que dificulta su escalado. Sin embargo, existe una biblioteca redux-dynamic-modules que permite la creación de reductores modulares y middleware.
- Modificabilidad . Personalizar Redux es un asunto sin esfuerzo porque admite middleware.
- Reutilización . Redux es independiente del marco, por lo que es muy bueno en la reutilización.
- ecosistema Redux ofrece un ecosistema gigante de complementos, bibliotecas y herramientas útiles.
- comunidad Redux, la biblioteca de gestión estatal más antigua de nuestra comparación, ha acumulado una gran comunidad con una importante base de conocimientos. Hay ~30 000 (~19 000 respondidas) preguntas con una etiqueta
reduxen Stack Overflow. - pulso Redux se actualiza y mantiene regularmente.
MobX
MobX es otra biblioteca relativamente antigua con 23 000 estrellas en GitHub. Lo que lo diferencia de Redux es que sigue el paradigma OOP y usa observables. MobX fue creado por Michel Weststrate y actualmente lo mantiene un grupo de entusiastas del código abierto con la ayuda de Mendix, con sede en Boston.
En MobX, crea una clase de JavaScript con una llamada makeObservable dentro del constructor que es su tienda observable (puede usar el decorador @observable si tiene el cargador apropiado). Luego declara propiedades (estado) y métodos ( acciones y valores calculados ) de la clase. Los componentes se suscriben a este almacén observable para acceder al estado, los valores calculados y las acciones.
Otra característica esencial de MobX es la mutabilidad. Permite actualizar el estado de forma silenciosa por si quieres evitar efectos secundarios.
Ejemplo de la API de MobX
Una característica única de MobX es que creas clases ES6 casi puras con toda la magia oculta bajo el capó. Requiere menos código específico de biblioteca para mantener la concentración en la lógica.
CódigoSandbox
// stores/counter.js import { makeAutoObservable } from "mobx"; class CounterStore { value = 0; constructor() { makeAutoObservable(this); } increment() { this.value += 1; } decrement() { this.value -= 1; } } export default CounterStore; // index.js import React from "react"; import ReactDOM from "react-dom"; import { Provider } from "mobx-react"; import App from "./App"; import CounterStore from "./stores/counter"; ReactDOM.render( <Provider counter={new CounterStore()}> <App /> </Provider>, document.getElementById("root") ); // App.js import React from "react"; import { inject, observer } from "mobx-react"; const App = inject((stores) => ({ counter: stores.counter }))( observer(({ counter }) => { return ( <div> <div> <button onClick={() => counter.increment()}>Increment</button> <span>{counter.value}</span> <button onClick={() => counter.decrement()}>Decrement</button> </div> </div> ); }) ); export default App;Atributos de calidad
- Usabilidad . Una tienda observable es el único punto de entrada para la gestión del estado. Hace que el uso de MobX sea simple porque tiene el único lugar para modificar.
- Mantenibilidad . Es un inconveniente considerable. Sin el conocimiento de la API de RxJS, no podrá lograr el resultado deseado. El uso de MobX en un equipo poco calificado puede generar problemas de inconsistencia de estado.
- rendimiento MobX consta de tiendas independientes y le permite suscribirse a las únicas que necesita. es muy efectivo
- Testabilidad . Las tiendas observables son objetos simples de JavaScript con una funcionalidad reactiva oculta en su interior. La prueba es la misma que para cualquier otra clase de JavaScript.
- Escalabilidad . Las tiendas observables se dividen lógicamente; no hay dificultad para escalar MobX.
- Modificabilidad . MobX permite crear observables personalizados con comportamientos modificados. Además, existe un concepto llamado reacciones. Las reacciones modelan los efectos secundarios automáticos. Estas cosas hacen que MobX sea muy personalizable.
- Reutilización . MobX es independiente de los marcos, por lo que es muy bueno en la reutilización.
- ecosistema Hay cientos de extensiones disponibles para MobX.
- comunidad MobX tiene muchos fanáticos devotos. Hay ~1600 (~1000 respondidas) preguntas con la etiqueta
mobxen Stack Overflow. - pulso MobX se actualiza y mantiene periódicamente.
Retroceso
Recoil es relativamente nuevo, la última creación del equipo de React. La idea básica detrás de esto es una implementación simple de las características de React que faltan, como el estado compartido y los datos derivados.

Quizás se pregunte por qué se revisa una biblioteca experimental para proyectos de nivel empresarial. En primer lugar, Recoil es uno de los temas más discutidos en la comunidad de React en este momento. En segundo lugar, Recoil está respaldado por Facebook y ya se usa en algunas de sus aplicaciones, por lo que en algún momento se convertirá en una versión estable. Finalmente, es un enfoque completamente nuevo para compartir el estado en React, y estoy seguro de que incluso si Recoil está obsoleto, habrá otra herramienta que siga el mismo camino.
El retroceso se basa en dos términos: átomo y selector . Un átomo es una pieza de estado compartido. Un componente puede suscribirse a un átomo para obtener/establecer su valor.
Como puede ver en la imagen, solo los componentes suscritos se vuelven a representar cuando se cambia el valor. Hace que Recoil sea muy eficaz.
Otra gran cosa que Recoil tiene lista para usar es el selector . El selector es un valor agregado de un átomo u otro selector. Para los consumidores, no hay diferencia entre atom y selector, solo necesitan suscribirse a alguna parte reactiva y usarla.
Cada vez que se cambia un átomo/selector, los selectores que lo usan (es decir, están suscritos a él) se vuelven a evaluar.
Ejemplo de API de retroceso
El código de Recoil es mucho más diferente al de sus competidores. Se basa en los ganchos de React y se centra más en la estructura del estado que en la mutación de este estado.
CódigoSandbox
// atoms/counter.js import { atom } from "recoil"; const counterAtom = atom({ key: "counter", default: 0 }); export default counterAtom; // index.js import React from "react"; import ReactDOM from "react-dom"; import { RecoilRoot } from "recoil"; import App from "./App"; ReactDOM.render( <RecoilRoot> <App /> </RecoilRoot>, document.getElementById("root") ); // App.js import React from "react"; import { useRecoilState } from "recoil"; import counterAtom from "./atoms/counter"; const App = () => { const [count, setCount] = useRecoilState(counterAtom); return ( <div> <div> <button onClick={() => setCount(count + 1)}>Increment</button> <span>{count}</span> <button onClick={() => setCount(count - 1)}>Decrement</button> </div> </div> ); }; export default App;Atributos de calidad
- Usabilidad . Recoil es una de las herramientas más fáciles de usar porque funciona como
useStateen React. - Mantenibilidad . Todo lo que tiene que hacer en Recoil es mantener selectores y ganchos dentro de los componentes: más valor, menos repetitivo.
- rendimiento Recoil construye un árbol de estado fuera de React. El árbol de estado le permite obtener y escuchar las cosas que necesita, no los cambios de todo el árbol. También está bien optimizado bajo el capó.
- Testabilidad . Recoil proporciona un mecanismo para probar sus átomos y selectores.
- Escalabilidad . Un estado que se divide en múltiples piezas independientes lo convierte en un buen jugador en escalabilidad.
- Modificabilidad . Recoil solo es responsable de almacenar valores y sus agregaciones. No tiene flujo de datos por lo que se puede personalizar fácilmente.
- Reutilización . El retroceso se basa en React. No se puede reutilizar en otro lugar.
- ecosistema No hay ecosistema para Recoil en este momento.
- comunidad Recoil es demasiado nuevo para tener una gran comunidad. Hay ~70 preguntas con la etiqueta
recoiljsen Stack Overflow. - pulso Recoil se actualiza con poca frecuencia (seis meses transcurridos entre sus dos actualizaciones más recientes). También tiene muchos problemas abiertos en GitHub.
Elegir la herramienta de gestión de estado de React adecuada
¿Cómo se comparan estas bibliotecas de administración de estado global de React cuando se trata de aplicaciones de nivel empresarial?
Recoil es joven y fresco, pero no tiene comunidad ni ecosistema en este momento. Aunque Facebook está trabajando en ello y la API parece prometedora, una gran aplicación React no puede depender de una biblioteca con un apoyo comunitario débil. Además, es experimental, lo que lo hace aún más inseguro. Definitivamente no es una buena opción para las aplicaciones empresariales de React hoy en día, pero vale la pena echarle un vistazo.
MobX y Redux no comparten ninguno de estos problemas y la mayoría de los grandes jugadores del mercado los usan. Lo que los hace diferentes entre sí es la curva de aprendizaje. MobX requiere una comprensión básica de la programación reactiva. Si los ingenieros involucrados en el proyecto no tienen la habilidad suficiente, la aplicación puede terminar con inconsistencias en el código, problemas de rendimiento y un mayor tiempo de desarrollo. MobX es aceptable y satisfará sus necesidades si su equipo es consciente de la reactividad.
Redux también tiene algunos problemas, principalmente relacionados con la escalabilidad y el rendimiento. Sin embargo, a diferencia de MobX, existen soluciones comprobadas para estos problemas.
Teniendo en cuenta todas las ventajas y desventajas, y considerando mi experiencia personal, recomiendo Redux como la mejor opción para las aplicaciones React de nivel empresarial.
