Die besten React State Management Tools für Unternehmensanwendungen
Veröffentlicht: 2022-03-11Entwickler von React-Anwendungen auf Unternehmensebene wissen, wie wichtig die Zustandsverwaltung für ein kohärentes Endbenutzererlebnis ist.
Der Benutzer ist jedoch nicht der einzige, der von der Zustandsverwaltung betroffen ist. React-Entwickler erstellen und pflegen Zustände. Sie möchten, dass die Zustandsverwaltung einfach, erweiterbar und atomar ist. React hat sich in diese Richtung bewegt, indem es Hooks eingeführt hat.
Probleme können auftreten, wenn der Zustand von vielen Komponenten geteilt werden soll. Ingenieure müssen Tools und Bibliotheken finden, die ihren Anforderungen entsprechen, aber gleichzeitig die hohen Standards erfüllen, die für Apps der Enterprise-Klasse erforderlich sind.
In diesem Artikel werde ich die beliebtesten Bibliotheken analysieren und vergleichen und die am besten geeignete für die Zustandsverwaltung in einer Anwendung auf Unternehmensebene auswählen.
Integrierte React State Management-Funktionen
React verfügt über ein hervorragendes Tool zum Bereitstellen von Daten über mehrere Komponenten hinweg. Das primäre Ziel von Context ist es, Prop-Drilling zu vermeiden. Unser Ziel ist es, ein benutzerfreundliches Tool zum Verwalten des Zustands in verschiedenen Szenarien zu erhalten, die wahrscheinlich in Unternehmensanwendungen auftreten: häufige Updates, Neugestaltungen, die Einführung neuer Funktionen und so weiter.
Obwohl all dies theoretisch mit Context machbar ist, würde es eine benutzerdefinierte Lösung erfordern, deren Einrichtung, Support und Optimierung Zeit erfordert. Der einzige Vorteil von Context besteht darin, dass es nicht von einer Bibliothek eines Drittanbieters abhängig ist, aber das kann den Aufwand für die Pflege dieses Ansatzes nicht aufwiegen.
Darüber hinaus hat Sebastian Markbage, Mitglied des React-Teams, erwähnt, dass die neue Kontext-API nicht für hochfrequente Updates entwickelt und optimiert wurde, sondern für niedrigfrequente Updates wie Theme-Updates und Authentifizierungsverwaltung.
Prüfung bestehender Bibliotheken
Auf GitHub gibt es Dutzende von Zustandsverwaltungstools (z. B. Redux, MobX, Akita, Recoil und Zustand). Jede von ihnen zu berücksichtigen, würde jedoch zu endlosen Recherchen und Vergleichen führen. Aus diesem Grund habe ich meine Auswahl auf die drei Hauptkonkurrenten eingegrenzt, basierend auf ihrer Popularität , Verwendung und Betreuer .
Um den Vergleich explizit zu machen, verwende ich die folgenden Qualitätsattribute:
- Benutzerfreundlichkeit
- Wartbarkeit
- Leistung
- Testbarkeit
- Skalierbarkeit (funktioniert mit der gleichen Leistung auf den größeren Zuständen)
- Änderbarkeit
- Wiederverwendbarkeit
- Ökosystem (verfügt über eine Vielzahl von Hilfswerkzeugen, um die Funktionalität zu erweitern)
- Community (hat viele Benutzer und ihre Fragen werden im Web beantwortet)
- Portabilität (kann mit anderen Bibliotheken/Frameworks als React verwendet werden)
Redux
Redux ist ein Zustandscontainer, der 2015 erstellt wurde. Er wurde sehr beliebt, weil:
- Als es auf den Markt kam, gab es keine ernsthafte Alternative.
- Es sah eine Trennung zwischen Staat und Handlungen vor.
-
react-reduxMagic ermöglichte eine einfache Zustandsverbindung. - Der Mitgestalter der Bibliothek ist der gefeierte Facebook-Entwickler und React-Kernteammitglied Dan Abramov.
Sie haben einen globalen Speicher, in dem Ihre Daten gespeichert sind. Wann immer Sie den Store aktualisieren müssen, senden Sie eine Aktion , die an den Reducer geht. Je nach Aktionstyp aktualisiert der Reducer den Zustand unveränderlich.
Um Redux mit React zu verwenden, müssen Sie die Komponenten für die Store-Updates über react-redux abonnieren.
Redux-API-Beispiel
Die grundlegenden Teile von Redux in der Codebasis, die es von den anderen Tools unterscheidet, sind Slices. Sie enthalten die gesamte Logik von Aktionen und Reduzierern.
CodeSandbox
// 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;Qualitätsattribute
- Benutzerfreundlichkeit . Redux wurde mit der Einführung des offiziellen Toolkit-Pakets sehr einfach. Sie erstellen ein Slice (eine Kombination aus Anfangszustand, Reducern und Aktionen), übergeben es an den Store und greifen in einer Komponente über Hooks darauf zu.
- Wartbarkeit . Redux ist einfach. Es erfordert kein tiefes Wissen, um zu verstehen, wie man etwas verbessert oder repariert.
- Leistung . Der primäre Leistungsbeeinflusser bei Redux ist der Softwareentwickler. Redux ist ein einfaches Tool ohne viel Logik. Wenn Sie feststellen, dass Statusaktualisierungen langsam sind, können Sie die offiziellen Richtlinien befolgen, um sie schneller zu machen.
- Prüfbarkeit . Redux besteht aus reinen Funktionen (Aktionen und Reducer), wodurch es sich hervorragend für Unit-Tests eignet. Es bietet auch den Mechanismus zum Schreiben von Integrationstests, bei denen der Speicher, die Aktionen und die Reduzierer zusammenarbeiten.
- Skalierbarkeit . Standardmäßig hat Redux einen globalen Zustand, was die Skalierung erschwert. Es gibt jedoch eine Redux-Dynamic-Modules-Bibliothek, die die Erstellung modularer Reducer und Middleware ermöglicht.
- Änderbarkeit . Das Anpassen von Redux ist eine mühelose Angelegenheit, da es Middleware unterstützt.
- Wiederverwendbarkeit . Redux ist Framework-agnostisch und daher sehr gut wiederverwendbar.
- Ökosystem . Redux bietet ein riesiges Ökosystem hilfreicher Add-Ons, Bibliotheken und Tools.
- Gemeinschaft . Redux, die älteste staatliche Verwaltungsbibliothek in unserem Vergleich, hat eine große Community mit einer bedeutenden Wissensbasis aufgebaut. Es gibt ~30.000 (~19.000 beantwortete) Fragen mit einem
redux-Tag auf Stack Overflow. - Puls . Redux wird regelmäßig aktualisiert und gepflegt.
MobX
MobX ist eine weitere relativ alte Bibliothek mit 23.000 Sternen auf GitHub. Was es von Redux unterscheidet, ist, dass es dem OOP-Paradigma folgt und Observables verwendet. MobX wurde von Michel Weststrate entwickelt und wird derzeit von einer Gruppe von Open-Source-Enthusiasten mit Hilfe von Mendix aus Boston gepflegt.
In MobX erstellen Sie eine JavaScript-Klasse mit einem makeObservable -Aufruf innerhalb des Konstruktors, der Ihr Observable Store ist (Sie können @observable decorator verwenden, wenn Sie über den entsprechenden Loader verfügen). Dann deklarieren Sie Eigenschaften (Status) und Methoden ( Aktionen und berechnete Werte ) der Klasse. Die Komponenten abonnieren diesen beobachtbaren Speicher, um auf den Zustand, berechnete Werte und Aktionen zuzugreifen.
Ein weiteres wesentliches Merkmal von MobX ist die Wandelbarkeit. Es ermöglicht die automatische Aktualisierung des Status, falls Sie Nebeneffekte vermeiden möchten.
MobX-API-Beispiel
Ein einzigartiges Merkmal von MobX ist, dass Sie fast reine ES6-Klassen mit all der Magie erstellen, die unter der Haube verborgen ist. Es erfordert weniger bibliotheksspezifischen Code, um die Konzentration auf die Logik zu halten.
CodeSandbox

// 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;Qualitätsattribute
- Benutzerfreundlichkeit . Ein beobachtbarer Speicher ist der einzige Einstiegspunkt für die Zustandsverwaltung. Es macht die Verwendung von MobX einfach, da Sie den einzigen Ort zum Ändern haben.
- Wartbarkeit . Es ist ein erheblicher Nachteil. Ohne Kenntnisse der RxJS-API können Sie das gewünschte Ergebnis nicht erzielen. Die Verwendung von MobX in einem schlecht qualifizierten Team kann zu Problemen mit Zustandsinkonsistenzen führen.
- Leistung . MobX besteht aus unabhängigen Geschäften und ermöglicht es Ihnen, nur die zu abonnieren, die Sie benötigen. Es ist sehr effektiv.
- Prüfbarkeit . Observable Stores sind einfache JavaScript-Objekte mit darin versteckter reaktiver Funktionalität. Das Testen ist dasselbe wie für jede andere JavaScript-Klasse.
- Skalierbarkeit . Observable Stores sind logisch aufgeteilt; MobX lässt sich problemlos skalieren.
- Änderbarkeit . MobX ermöglicht das Erstellen benutzerdefinierter Observables mit geändertem Verhalten. Darüber hinaus gibt es ein Konzept namens Reaktionen. Reaktionen modellieren automatische Nebenwirkungen. Diese Dinge machen MobX sehr anpassbar.
- Wiederverwendbarkeit . MobX ist unabhängig von Frameworks und daher sehr gut in der Wiederverwendbarkeit.
- Ökosystem . Es gibt Hunderte von Erweiterungen für MobX.
- Gemeinschaft . MobX hat viele treue Fans. Es gibt ~1.600 (~1.000 beantwortete) Fragen mit dem
mobx-Tag auf Stack Overflow. - Puls . MobX wird regelmäßig aktualisiert und gewartet.
Rückstoß
Recoil ist ein relativer Newcomer, die neueste Idee des React-Teams. Die Grundidee dahinter ist eine einfache Implementierung fehlender React-Features wie Shared State und abgeleitete Daten.
Sie fragen sich vielleicht, warum eine experimentelle Bibliothek für Projekte auf Unternehmensebene überprüft wird. Zunächst einmal ist Recoil derzeit eines der am meisten diskutierten Themen in der React-Community. Zweitens wird Recoil von Facebook unterstützt und bereits in einigen seiner Anwendungen verwendet, was bedeutet, dass es irgendwann eine stabile Version werden wird. Schließlich ist es ein völlig neuer Ansatz für die gemeinsame Nutzung von Zuständen in React, und ich bin sicher, dass selbst wenn Recoil veraltet ist, es ein anderes Tool geben wird, das dem gleichen Weg folgt.
Rückstoß basiert auf zwei Begriffen: Atom und Selektor . Ein Atom ist ein Shared-State-Stück. Eine Komponente kann ein Atom abonnieren, um seinen Wert zu erhalten/einzustellen.
Wie Sie im Bild sehen können, werden nur die abonnierten Komponenten neu gerendert, wenn der Wert geändert wird. Es macht Recoil sehr leistungsfähig.
Eine weitere großartige Sache, die Recoil sofort einsatzbereit hat, ist der Selektor . Der Selektor ist ein Wert, der von einem Atom oder einem anderen Selektor aggregiert wird. Für Verbraucher gibt es keinen Unterschied zwischen Atom und Selektor, sie müssen nur einen reaktiven Teil abonnieren und ihn verwenden.
Immer wenn ein Atom/Selektor geändert wird, werden die Selektoren, die ihn verwenden (dh ihn abonniert haben), neu bewertet.
Rückstoß-API-Beispiel
Der Code von Recoil ist weitaus anders als der seiner Konkurrenten. Es basiert auf React-Hooks und konzentriert sich mehr auf die Zustandsstruktur als auf die Mutation dieses Zustands.
CodeSandbox
// 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;Qualitätsattribute
- Benutzerfreundlichkeit . Recoil ist eines der am einfachsten zu verwendenden Tools, da es wie
useStatein React funktioniert. - Wartbarkeit . Alles, was Sie in Recoil tun müssen, ist, Selektoren und Haken in den Komponenten zu warten – mehr Wert, weniger Boilerplate.
- Leistung . Recoil erstellt einen Zustandsbaum außerhalb von React. Der Zustandsbaum ermöglicht es Ihnen, die Dinge, die Sie benötigen, abzurufen und anzuhören, nicht die Änderungen des gesamten Baums. Es ist auch unter der Haube gut optimiert.
- Prüfbarkeit . Recoil bietet einen Mechanismus zum Testen seiner Atome und Selektoren.
- Skalierbarkeit . Ein Zustand, der sich in mehrere unabhängige Teile aufteilt, macht ihn zu einem guten Akteur bei der Skalierbarkeit.
- Änderbarkeit . Recoil ist nur für das Speichern von Werten und deren Aggregationen verantwortlich. Es hat keinen Datenfluss und kann daher einfach angepasst werden.
- Wiederverwendbarkeit . Recoil setzt auf React. Es kann nicht an anderer Stelle wiederverwendet werden.
- Ökosystem . Derzeit gibt es kein Ökosystem für Recoil.
- Gemeinschaft . Recoil ist zu frisch, um eine große Community zu haben. Es gibt ~70 Fragen mit
recoiljs-Tag auf Stack Overflow. - Puls . Recoil wird selten aktualisiert (sechs Monate sind zwischen den beiden letzten Updates vergangen). Es hat auch viele offene Probleme auf GitHub.
Auswahl des richtigen React State Management Tools
Wie schneiden diese React Global State Management Libraries ab, wenn es um Apps der Enterprise-Klasse geht?
Recoil ist jung und frisch, hat aber im Moment weder eine Community noch ein Ökosystem. Auch wenn Facebook daran arbeitet und die API vielversprechend erscheint, kann sich eine riesige React-Anwendung nicht auf eine Bibliothek mit schwacher Community-Unterstützung verlassen. Außerdem ist es experimentell, was es noch unsicherer macht. Es ist heute definitiv keine gute Option für React-Unternehmensanwendungen, aber es lohnt sich, es im Auge zu behalten.
MobX und Redux teilen keines dieser Probleme und die meisten großen Player auf dem Markt verwenden sie. Was sie voneinander unterscheidet, ist die Lernkurve. MobX erfordert ein grundlegendes Verständnis der reaktiven Programmierung. Wenn die am Projekt beteiligten Ingenieure nicht qualifiziert genug sind, kann die Anwendung zu Code-Inkonsistenzen, Leistungsproblemen und verlängerter Entwicklungszeit führen. MobX ist akzeptabel und erfüllt Ihre Anforderungen, wenn Ihr Team sich der Reaktivität bewusst ist.
Redux hat auch einige Probleme, hauptsächlich in Bezug auf Skalierbarkeit und Leistung. Im Gegensatz zu MobX gibt es jedoch bewährte Lösungen für diese Probleme.
Unter Berücksichtigung aller Vor- und Nachteile und unter Berücksichtigung meiner persönlichen Erfahrung empfehle ich Redux als die beste Option für React-Anwendungen auf Unternehmensebene.
