webentwicklung-frage-antwort-db.com.de

Gibt es einen Platz für OOP in Redux?

Ich verwende seit 25 Jahren objektorientierte Programmierpraktiken und versuche in den letzten 5 Jahren, mich der funktionalen Programmierung zuzuwenden, aber ich denke immer an OOP, wenn ich versuche, etwas Komplexes zu tun und Besonders jetzt, wo ES6 eine anständige OOP -Syntax unterstützt, ist dies für mich die natürliche Art, Dinge zu erstellen.

Ich lerne jetzt Redux und verstehe (vgl. Wie werden Methoden auf die Objekte im Redux-Status angewendet? ), dass es ein Nein-Nein ist, Klasseninstanzen in Ihre Reduzierungen zu setzen. und das empfohlene Verfahren zum Berechnen über den normalen Reduzierzustand besteht in der Verwendung von Selektoren (z. B. durch erneutes Auswählen). Und natürlich empfiehlt React die Komposition über die Vererbung ( https://facebook.github.io/react/docs/composition-vs-inheritance.html , React redux oop classes ).

Aber gibt es im React/Redux-Ökosystem einen Platz für Klassenobjekte mit Methoden und Vererbung?

Um meine eigene Frage zu beantworten: OOP Klassen fördern das Hinzufügen von Dateneigenschaften und -operationen zu den Daten an derselben Stelle. Dies ist gut für die Lesbarkeit, passt aber nicht gut zu reinen Funktionen und unveränderliche Daten.

Wenn ich OOP verwenden würde, müsste ich die Idee verwerfen, dass meine Instanzen bestehen bleiben und den Status für eine beliebige Zeitdauer beibehalten? Jedes Mal, wenn ich eines verwenden möchte, würde ich es aus den Geschäftsdaten instanziieren, die von mir gewünschten Methoden verwenden und es wegwerfen. Dies könnte einen Großteil des Impulses, OOP Klassen zu verwenden, vermeiden. Aber wenn ich die Instanzen in der Nähe halte, werden die Kopfschmerzen mit dem Geschäft synchronisiert.

Ist die Antwort also, immer Selektoren zu verwenden, wenn ich versucht bin, Methoden zu verwenden, und immer Komposition zu verwenden, wenn ich versucht bin, Vererbung zu verwenden? Konkret meine ich, wenn Daten in einem Redux-Speicher für die Verwendung in React-Komponenten gespeichert und bearbeitet werden. Und wenn ja, wohin sollte es passen? Verbunden mit Selektoren? Sofort verfügbar, wie ich vorgeschlagen habe?


Der Klarheit halber füge ich meinen Anwendungsfall hinzu: Meine Daten sind im Grunde genommen ein riesiges Diagramm: viele Objekte mit vielen Eigenschaften und vielen Beziehungen zwischen Objekten. Es ist schreibgeschützt, aber komplex. Meine Objekte heißen "Konzepte".

Bevor ich die (wahrscheinlich dumme) Entscheidung traf, nach Redux zu migrieren, verwendete ich Klassen, um Konzepte, Konzeptsätze und Beziehungen zwischen Konzepten zu strukturieren und darzustellen. Meine Klassen umfassten asynchrone API-Logik zum Abrufen von Konzeptsätzen, Informationen zu jedem Konzept und Informationen zu anderen Konzepten, mit denen jedes Konzept verwandt ist. Wenn der Benutzer einen Drilldown auswählt, rufen die Klassen rekursiv neue Konzeptsätze ab und instanziieren sie. Die Redux-Dokumentation empfiehlt flache, normalisierte Strukturen für verschachtelte Daten ( http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html ), was für die Speicherung wahrscheinlich sinnvoll ist, aber mein OOP Modell war gut für das Durchqueren von Abschnitten des Graphen und so. Es fällt mir schwer, mich mit Selektoren und unveränderlichen Zuständen zu beschäftigen, bei denen es sich möglicherweise um Verschachtelungen handelt, die zyklisch ablaufen oder bei denen ich asynchrone Aufrufe für mehr Daten ausführen muss.

Ich verwende https://redux-observable.js.org/ erfolgreich für das API-Zeug.

Vielleicht ist die Antwort von @ Sulthan richtig: Ich sollte mich frei fühlen, OOP Techniken in meiner Redux-Anwendung zu verwenden. Aber es scheint immer noch komisch. Ich kann meine Objekte nicht aufbewahren, da meine Objekte veralten können, wenn sich der Speicher ändert (z. B. wenn mehr Daten abgerufen werden). Wenn meine Objekte verschachtelt sind, aber mein Geschäft normalisiert ist, instanziiere ich sie (von Selektoren), wenn ich sie benötige, und stelle sicher, dass sie nicht in der Nähe sind ...

17
Sigfried

Ich beantworte meine eigene Frage, indem ich beschreibe, was ich getan habe, so unvollkommen wie es ist.

Erstens habe ich anstelle der regulären ES6-Klassensyntax angefangen, stampit zu verwenden, was hässlicher ist als die ES6-Klassen, aber viel flexibler.

Meine komplexen Objekte existieren jedoch hauptsächlich in zwei Formen: 

  • einfache JS-Objekte für den Store
  • instanzen der Klasse (tatsächlich gestempelt) zur Vereinfachung und Verwendung von Instanzmethoden.

Ich benutze eine Konvention, um einen _underscore vor allen Verweisen auf die einfachen Objekte zu setzen. Meine "Lösung" ist aus vielen Gründen kludig und schlecht, aber ich denke, der Versuch, Selektoren für alles zu verwenden, wäre schlimmer. Wenn Sie neugierig sind, ist hier der Platz in meinem Code, an dem ich meine einfachen Speicherobjekte in Instanzen "aufblase": https://github.com/Sigfried/vocab-pop/blob/localstorage/src/ducks/conceptSet. js # L292

</ s>

AKTUALISIEREN

Es ist eine schreckliche Idee, Redux-State-POJOs in Klasseninstanzen (regulär oder gestempelt) umzuwandeln.

Ich hätte die Antwort von @ markerikson wahrscheinlich annehmen sollen, und vielleicht ist das Redux-ORM-Ding einen Blick wert, aber ich wollte nur definitiv sagen: TUN SIE NICHT, WAS ICH TAT. (Ich denke immer, dass ich so klug bin, die "Lücken" der Technologien auszufüllen, die ich mit klugen Hacks lerne - und dann verbringe ich schmerzhafte Monate damit, den Schlamassel aufzuräumen, sobald ich verstanden habe, warum diese Technologie meinen Hacker nicht in die erster Platz.)

Noch ein Update

Von Composing Software: Eine Einführung :

Was wir nicht tun, ist zu sagen, dass die funktionale Programmierung besser ist als die objektorientierte Programmierung, oder dass Sie eine andere als die Andere auswählen müssen. OOP vs FP ist eine falsche Dichotomie. Jede echte Javascript - Anwendung, die ich in den letzten Jahren gesehen habe, mischt FP und OOP ausgiebig.

Anscheinend gibt es gute Möglichkeiten, über die Kombination von FP und OOP nachzudenken, und es wird ohne Zweifel einige unveränderliche Klassen und Kompositionen ohne viel Vererbung verwenden. Diese Serie über Komposition sieht aus wie das, was ich lernen musste.

8
Sigfried

Die Antwort ist, dass es möglich ist, aber stark entmutigt und nicht idiomatisch ist.

React stützt sich auf Klassen und die Vererbung von React.Component auf einer Ebene, um zustandsbehaftete Komponenten mit Lebenszyklen zu implementieren. Es wird jedoch offiziell davon abgeraten, weitere Vererbungsebenen in Komponenten durchzuführen.

Redux basiert auf Funktionsprinzipien. Aus verschiedenen Gründen sollten Sie Ihren Status als reine JS-Objekte und Arrays beibehalten und mit einfachen Funktionen darauf zugreifen bzw. ihn bearbeiten.

Ich habe sicherlich viele Bibliotheken gesehen, die versuchten, eine OOP -Ebene oberhalb von Redux hinzuzufügen (z. B. Klassen, deren Methoden in Aktionsersteller und -reduzierer umgewandelt werden). Die Arbeit , sind aber definitiv gegen den Gesamtgeist von Redux.

Ich benutze tatsächlich eine Bibliothek namens Redux-ORM , die do erlaubt, Modellklassen zu definieren, die als Fassade über den einfachen JS-Objekten in Ihrem Geschäft fungieren. Im Gegensatz zu vielen anderen Bibliotheken, die ich gesehen habe, funktioniert es jedoch with Redux, anstatt zu versuchen, das Verhalten von Redux zu ändern. Wie Redux-ORM funktioniert, wie ich es benutze und warum es noch einigermaßen idiomatisch ist, habe ich in meinen Blogbeiträgen besprochen Praktische Redux, Teil 1: Grundlagen von Redux-ORM und Praktische Redux, Teil 2: Redux-ORM Konzepte und Techniken . Alles in allem ist dies ein hervorragendes Werkzeug für die Verwaltung von Beziehungen und normalisierten Daten in Ihrem Redux Store.

Schließlich arbeite ich gerade an einem Blogbeitrag, in dem die tatsächlichen technischen Einschränkungen erläutert werden, die Redux erfordert (und warum), vs wie Sie sind beabsichtigt Redux verwenden, vs wie es möglich ist um Redux zu benutzen. Ich hoffe, dass ich das in der nächsten Woche oder so haben kann - achten Sie auf http://blog.isquaredsoftware.com .

10
markerikson

Diese Frage ist ein bisschen meinungsbasiert, aber konzentrieren wir uns auf die Kernpunkte.

Es gibt keinen Widerspruch zwischen funktionaler Programmierung und OOP. Sie müssen nur die gleichen Programmiermuster verwenden. Es ist kein Problem, Klassen (mit Vererbung) in der funktionalen Programmierung zu verwenden, wenn Sie sie unveränderlich lassen.

Um meinen Standpunkt zu beweisen, besteht die beliebte Bibliothek Immutable.js , die von vielen Leuten verwendet wird, um den Status in redux aufrechtzuerhalten, aus classes . Und diese Klassen haben Vererbung (z. B. OrderedSet extends Set).

Beachten Sie auch, dass die meisten React-Komponenten classes sind und auch die Vererbung verwenden (... extends React.Component).

1
Sulthan