Eine Einführung in Redux-Logic

Dieser Artikel enthält eine allgemeine Übersicht über Redux-Logic. Wir werden uns ansehen, was es ist, warum es benötigt wird, wie es sich von anderen Redux-Middleware unterscheidet und warum es meiner Meinung nach die beste Wahl ist. Wir werden dann ein Beispiel einer einfachen Wetter-App sehen, um zu demonstrieren, wie die Kernkonzepte in die Praxis umgesetzt werden.

In diesem Artikel wird davon ausgegangen, dass Sie ein gutes Verständnis von React und Redux haben.

Eine kurze Auffrischung zu Redux

Redux ist ein Statuscontainer für JavaScript-Anwendungen und wird häufig mit React verwendet. Es bietet einen zentralen Ort zum Speichern von Daten, die in Ihrer Anwendung verwendet werden. Redux bietet auch einen Rahmen für vorhersagbare Zustandsmutationen. Die Verwendung von Redux erleichtert das Schreiben, Verstehen, Debuggen und Skalieren datengesteuerter und dynamischer Anwendungen.

In Redux rufen Komponenten Aktionsersteller auf, die Aktionen auslösen . Aktionen sind (normalerweise!) Kleine einfache Objekte, die eine Absicht oder eine Anweisung ausdrücken. Die Aktionen können auch 'Nutzdaten' (dh Daten) enthalten.

Der Anwendungsstatus wird von Reduzierern verwaltet . Sie klingen komplizierter als sie sind! Aktionen werden von einem Root-Reduzierer ausgeführt, der dann die Aktion und die Nutzlast an einen bestimmten Reduzierer weiterleitet. Das Reduzierstück wird eine Kopie nehmen des Anwendungszustands, mutiert die Kopie (nach der Aktion und ihre Nutzlast) und dann in den Zustand der Anwendung aktualisieren Shops .

Warum wird Redux Logic benötigt?

Standardmäßig werden alle Aktionen in Redux synchron ausgelöst. Dies ist eine Herausforderung für jede Anwendung, die asynchrones Verhalten unterstützen muss, z. B. das Abrufen von Daten von einer API… so ziemlich jede Anwendung!

Um das asynchrone Verhalten mit Redux zu verarbeiten, benötigen wir eine Art Middleware, die eine gewisse Verarbeitung zwischen dem Zeitpunkt des Versands der Aktion und dem Erreichen der Reduzierungen durchführt. Es gibt mehrere beliebte Bibliotheken, um diese Funktionalität bereitzustellen.

Nachdem ich die verschiedenen Optionen erkundet habe, verwende ich Redux-Logic seit einiger Zeit in einer Vielzahl von Projekten und finde es großartig!

Redux-Logic-Lebenszyklus

Redux-Logic bietet Middleware, die eine gewisse Verarbeitung zwischen dem Versand einer Aktion von einer Komponente und dem Erreichen eines Reduzierers durch die Aktion ausführt.

Wir verwenden die Redux-Logik-Bibliothek, um 'Logik' zu erstellen. Dies sind im Wesentlichen Funktionen, die bestimmte Aktionen für einfache Objekte abfangen , eine asynchrone Verarbeitung durchführen und dann eine weitere Aktion für einfache Objekte auslösen . Logikfunktionen sind wirklich deklarativ und flexibel, wie wir sehen werden!

Eine wichtige Sache, die Sie hier wegnehmen sollten, ist, dass alle Aktionen, mit denen Redux-Logic arbeitet, einfache Objekte sind . Die Aktion, die von der UI-Komponente ausgelöst wird, und die Aktion, die dann von der Logik ausgelöst wird, ist immer ein einfaches Objekt (im Gegensatz beispielsweise zu einer Funktion). Wir werden dies weiter unten noch einmal betrachten, wenn wir verschiedene Middleware-Optionen vergleichen.

Unter der Haube verwendet Redux-Logic 'Observables' und reaktive Programmierung. Lesen Sie hier mehr darüber.

Datenfluss

Zum Vergleich ist unten ein Diagramm dargestellt, das die wichtigen Punkte im Lebenszyklus eines synchronen Redux-Prozesses zeigt. Es ist keine Middleware enthalten (da keine benötigt wird!).

Hier ist ein Diagramm, das die wichtigen Teile eines Projekts zeigt, die die Redux-Logik-Bibliothek verwenden, um asynchrone Aktionen zu verarbeiten. Dies ist nützlich, um später neben dem folgenden Beispiel darauf zu verweisen.

Sie können sehen, wie die Middleware zwischen dem Auslösen einer Aktion und der Verarbeitung durch einen Reduzierer funktioniert.

Hauptunterschiede zu anderen Lösungen

Redux-Thunk ist eine beliebte Wahl für Redux-Middleware, mit der Sie auch asynchrones Verhalten unterstützen können. Um mit asynchronem Verhalten mit Redux-Thunk umzugehen, müssen Ihre Aktionsersteller Funktionen zurückgeben , anstatt einfache Objekte mit Redux-Logic zurückzugeben. Ich glaube, dass das Versenden einfacher Objekte mit Redux-Logic das Schreiben und Verstehen Ihres Codes erheblich erleichtert.

Darüber hinaus glaube ich, dass der "Plain Object" -Ansatz für den Umgang mit asynchronem Verhalten natürlicher zum Rest der (synchronen) Redux-Architektur passt, wodurch diese Middleware organischer zu Redux passt.

Eine weitere beliebte Redux-Middleware ist Redux-Saga . Ich fand die Lernkurve, mich mit Sagen zu beschäftigen (eine relativ neue ES6-Funktion), ziemlich steil, als ich mir diese Option ansah. Dies würde noch verstärkt, wenn Sie diese Bibliothek in eine Anwendung einführen möchten, die von einem Team mit mehreren Personen verwaltet wird. Außerdem denke ich, dass Sagen, wenn sie nicht gut verwaltet werden, im Vergleich zu der Logik, die Sie mit Redux-Logik erstellen, kompliziert aussehenden Code erstellen können. Dies kann sich auf die Entwicklungsgeschwindigkeit und die Wartbarkeit des Codes auswirken.

Beispielübersicht

Im Folgenden finden Sie einfache Ausschnitte aus einer einfachen React-Anwendung, mit der Sie die aktuellen Wetterbedingungen in einer Stadt abrufen und dem Benutzer präsentieren können. In diesem Beispiel wird Redux-Logic verwendet, um das asynchrone Verhalten beim Abrufen von Daten mithilfe einer kostenlosen OpenWeatherMap-API zu unterstützen.

Zum Vergleich habe ich einen synchronen Redux-Prozess eingefügt, der die Anzahl der von einem Benutzer gestellten Anforderungen anzeigt.

Hier ist der Quellcode.

Entwicklungsumgebung einrichten

Dies sind die Befehle, die ich ausgeführt habe, um mit der Erstellung meiner Anwendung zu beginnen:

npx create-react-app appnpm install --save reduxnpm install --save react-reduxnpm install --save redux-logicnpm install --save axios

Und um die App zu sehen:

npm start

Ich bin froh, dass ich die Standard-Startseite der Create React App bei localhost sehen konnte: 3000 , und habe dann angefangen, Code zu schreiben!

Unten finden Sie Codefragmente, die die wichtigen Punkte zur Integration von Redux-Logic in das Projekt zeigen.

Hinzufügen von Middleware zu unserem Redux-Shop

Wenn wir in appStore.js keine Middleware verwenden, stellen wir normalerweise nur unseren Root-Reduzierer für die createStore-Methode bereit. Hier verknüpfen wir unsere Redux-Logic-Middleware mit dem Rest unserer Anwendung.

Wir geben an, dass wir Axios als unseren Client für HTTP-Anfragen verwenden möchten .

Wir verwenden dann eine Methode aus der Redux-Logik, um unsere Middleware zu erstellen, und fügen sie schließlich als Parameter zur createStore-Methode hinzu. Dies bedeutet, dass unser Redux-Code auf unsere Middleware zugreifen kann. Toll!

Asynchrone Aktionen auslösen

Mit Redux-Logic werden Aktionen, die asynchrones Verhalten auslösen, auf dieselbe Weise ausgelöst wie Aktionen, die synchrone Statusaktualisierungen auslösen. Es gibt nichts anderes!

Der Vollständigkeit halber können Sie unten sehen, dass wir, wenn ein Benutzer auf eine Schaltfläche klickt, einen Aktionsersteller aufrufen, der als Requisiten an unsere Komponente übergeben wurde.

Asynchrone Aktionen abfangen

Hier kommt zum ersten Mal die Entstehung der Redux-Logic-Middleware ins Spiel. Wir verwenden die Redux-Logik-Bibliothek, um eine 'Logik' zu erstellen, die bestimmte Aktionen abfängt.

In unseren Logic-Eigenschaften teilen wir der Redux-Logik mit, welche Aktion sie abfangen soll. Wir geben an, dass die Redux-Logik nur Daten aus der letzten Aktion dieses Typs bereitstellen soll, die die Komponente ausgelöst hat. In unserem Beispiel ist dieses deklarative Verhalten nützlich, wenn Benutzer weiterhin auf eine Schaltfläche klicken, da sie den Wert der letzten Aktion erhalten, die sie gesendet haben, und nicht unbedingt das letzte Versprechen, zurückzukehren!

Als nächstes werden wir festlegen , dass , wenn die asynchronen Prozess kehrt wir sofort versenden eine von zwei Aktionen. Wenn das Versprechen erfolgreich zurückgegeben wurde, geben wir eine Aktion GET_WEATHER_FOR_CITY_SUCCESSFUL zurück . Das wollen wir!

Wenn das zurückgegebene Versprechen abgelehnt wurde, versenden wir alternativ GET_WEATHER_FOR_CITY_FAILURE .

Hier strahlt die Redux-Logik wirklich . Es ist klar, was die Absicht des Logikcodes ist, und was ausgegeben wird, sind einfache Objekte, die leicht zu lesen und zu interpretieren sind! Ich finde das wirklich einfach zu lesen, zu verstehen und zu debuggen.

Unten machen wir deutlich, was unser asynchroner Prozess tun soll. Wir wollen den Wert eines Versprechens zurückgeben. Beachten Sie, wie wir die mit unserer Aktion gelieferte Nutzlast an die URL übergeben.

Asynchrone Aktionen verarbeiten

Sie können dem Reducer von weatherDataHandling.js entnehmen, dass die von unserer Logik ausgelösten Aktionen dann als einfache Objektaktionen behandelt werden. Reduzierer mutieren den Zustand auf die gleiche Weise wie bei synchronen Aktionen . Der folgende Screenshot ist also das, was Sie von einer früheren Arbeit mit Redux erwarten würden. Super!

Zusammenfassung

Redux ist ein beliebter vorhersehbarer Statuscontainer für JavaScript-Anwendungen. Standardmäßig unterstützen alle Redux-Aktionen nur synchrones Verhalten, und Sie benötigen eine Middleware-Lösung für asynchrones Verhalten.

Redux-Logic bietet eine klare und leistungsstarke Middleware, mit der Sie asynchrone Aktionen in Ihrer Redux-Anwendung verwenden können. Sie fügen Ihre Middleware Ihrem Redux Store hinzu , damit Ihre Anwendung Redux-Logic verwenden kann. Sie verwenden die Redux-Logik-Bibliothek, um eine Logik zu erstellen, die bestimmte Aktionen abfängt und weitere Aktionen auslöst, nachdem eine asynchrone Verarbeitung (z. B. das Abrufen von Daten von einer API) abgeschlossen ist.

Alle beteiligten Aktionen sind einfache Objektaktionen. Ich glaube, dies erleichtert das Schreiben und Verstehen im Vergleich zu anderen Lösungen. Darüber hinaus scheint sich die Redux-Logik organischer in die anderen Teile der Redux-Architektur einzufügen.

Vielen Dank fürs Lesen, ich freue mich über Kommentare oder Fragen unten!