Advertisement
  1. Code
  2. React

Eine sanfte Einführung in Komponenten höherer Ordnung in Reaktion: Best Practices

by
Difficulty:BeginnerLength:LongLanguages:

German (Deutsch) translation by Federicco Ancie (you can also view the original English article)

Dies ist der dritte Teil der Reihe über Komponenten höherer Ordnung. Im ersten Tutorial haben wir mit Ground Zero begonnen. Wir haben die Grundlagen der ES6-Syntax, Funktionen höherer Ordnung und Komponenten höherer Ordnung gelernt.

Das Komponentenmuster höherer Ordnung ist nützlich, um abstrakte Komponenten zu erstellen. Sie können sie verwenden, um Daten (Status und Verhalten) mit Ihren vorhandenen Komponenten zu teilen. Im zweiten Teil der Serie habe ich anhand dieses Musters praktische Beispiele für Code demonstriert. Dies umfasst geschützte Routen, das Erstellen eines konfigurierbaren generischen Containers, das Anhängen einer Ladeanzeige an eine Komponente usw.

In diesem Tutorial werden einige bewährte Methoden und Vor- und Nachteile vorgestellt, die Sie beim Schreiben von HOCs beachten sollten.

Einführung

React hatte zuvor so etwas wie Mixins, was mit der React.createClass-Methode hervorragend funktionierte. Mit Mixins konnten Entwickler Code zwischen Komponenten austauschen. Sie hatten jedoch einige Nachteile, und die Idee wurde schließlich fallen gelassen. Mixins wurden nicht aktualisiert, um ES6-Klassen zu unterstützen, und Dan Abramov schrieb sogar einen ausführlichen Beitrag darüber, warum Mixins als schädlich angesehen werden.

Komponenten höherer Ordnung stellten sich als Alternative zu Mixins heraus und unterstützten ES6-Klassen. Darüber hinaus müssen HOCs nichts mit der React-API tun und sind ein generisches Muster, das gut mit React funktioniert. HOCs weisen jedoch auch Mängel auf. Obwohl die Nachteile von Komponenten höherer Ordnung in kleineren Projekten möglicherweise nicht erkennbar sind, können mehrere Komponenten höherer Ordnung wie unten beschrieben mit einer einzelnen Komponente verkettet sein.

Sie sollten nicht zulassen, dass die Verkettung an den Punkt kommt, an dem Sie sich die Frage stellen: "Woher kommen diese Requisiten?" Dieses Tutorial behandelt einige der häufigsten Probleme mit Komponentenmustern höherer Ordnung und die Lösungen, um sie richtig zu machen.

Die Probleme mit HOC

Einige der häufigsten Probleme im Zusammenhang mit HOCs haben weniger mit HOCs selbst zu tun, als vielmehr mit Ihrer Implementierung.

Wie Sie bereits wissen, eignen sich HOCs hervorragend für die Code-Abstraktion und die Erstellung von wiederverwendbarem Code. Wenn Sie jedoch mehrere HOCs gestapelt haben und etwas nicht stimmt oder wenn einige Requisiten nicht angezeigt werden, ist das Debuggen schmerzhaft, da die React DevWerkzeugs Ihnen nur einen sehr begrenzten Hinweis darauf geben, was möglicherweise schief gelaufen ist.

Ein reales HOC-Problem

Um die Nachteile von HOCs zu verstehen, habe ich eine Beispieldemo erstellt, in der einige der HOCs verschachtelt sind, die wir im vorherigen Lernprogramm erstellt haben. Wir haben vier Funktionen höherer Ordnung, die diese einzelne ContactList-Komponente umschließen. Wenn der Code keinen Sinn ergibt oder Sie meinem vorherigen Tutorial nicht gefolgt sind, finden Sie hier eine kurze Zusammenfassung der Funktionsweise.

withRouter ist ein HOC, das Teil des React-Router-Pakets ist. Sie erhalten Zugriff auf die Eigenschaften des Verlaufsobjekts und übergeben sie dann als Requisite.

withAuth sucht nach einer authentification prop und rendert die WrappedComponent, wenn die Authentifizierung wahr ist. Wenn die Authentifizierung falsch ist, wird '/login' an das Verlaufsobjekt gesendet.

withGenericContainer akzeptiert zusätzlich zur WrappedComponent ein Objekt als Eingabe. Der GenericContainer führt API-Aufrufe durch, speichert das Ergebnis im Status und sendet die Daten dann als Requisiten an die umschlossene Komponente.

withLoader ist ein HOC, das eine Ladeanzeige anfügt. Der Indikator dreht sich, bis die abgerufenen Daten den Status erreichen.

BestPracticeDemo.jsx

Jetzt können Sie sich selbst von den häufigsten Fallstricken von Komponenten höherer Ordnung überzeugen. Lassen Sie uns einige davon im Detail besprechen.

Grundlegende Dos und Don'ts

Vergessen Sie nicht, die Requisiten in Ihrem HOC zu verbreiten

Angenommen, wir haben eine authenticated = { this.state.authenticated } prop oben in der Kompositionshierarchie. Wir wissen, dass dies eine wichtige Stütze ist und dass dies bis zur Präsentationskomponente reichen sollte. Stellen Sie sich jedoch vor, dass ein Zwischen-HOC wie withGenericContainer beschlossen hat, alle seine Requisiten zu ignorieren.

Dies ist ein sehr häufiger Fehler, den Sie beim Schreiben von Komponenten höherer Ordnung vermeiden sollten. Jemand, der nicht mit HOCs vertraut ist, könnte es schwierig finden, herauszufinden, warum alle Requisiten fehlen, da es schwierig wäre, das Problem zu isolieren. Denken Sie also immer daran, die Requisiten in Ihrem HOC zu verteilen.

Geben Sie keine Requisiten weiter, die nicht über den Rahmen des HOC hinaus existieren

Ein HOC führt möglicherweise neue Requisiten ein, für die die WrappedComponent möglicherweise keine Verwendung hat. In solchen Fällen empfiehlt es sich, Requisiten weiterzugeben, die nur für die zusammengesetzten Komponenten relevant sind.

Eine Komponente höherer Ordnung kann Daten auf zwei Arten akzeptieren: entweder als Argument der Funktion oder als Requisite der Komponente. Beispielsweise ist authenticated = { this.state.authenticated } ein Beispiel für eine Requisite, während wir in withGenericContainer(reqAPI)(ContactList) die Daten als Argumente übergeben.

Da withGenericContainer eine Funktion ist, können Sie so wenige oder so viele Argumente übergeben, wie Sie möchten. Im obigen Beispiel wird ein Konfigurationsobjekt verwendet, um die Datenabhängigkeit einer Komponente anzugeben. Der Vertrag zwischen einer erweiterten Komponente und der verpackten Komponente erfolgt jedoch ausschließlich über Requisiten.

Ich empfehle daher, die statischen Zeitdatenabhängigkeiten über die Funktionsparameter auszufüllen und dynamische Daten als Requisiten zu übergeben. Die authentifizierten Requisiten sind dynamisch, da ein Benutzer entweder authentifiziert werden kann oder nicht, je nachdem, ob er angemeldet ist oder nicht. Wir können jedoch sicher sein, dass sich der Inhalt des reqAPI-Objekts nicht dynamisch ändert.

Verwenden Sie keine HOCs innerhalb der Rendermethode

Hier ist ein Beispiel, das Sie unbedingt vermeiden sollten.

Abgesehen von den Leistungsproblemen verlieren Sie bei jedem Rendern den Status der OriginalComponent und aller untergeordneten Elemente. Um dieses Problem zu lösen, verschieben Sie die HOC-Deklaration außerhalb der Rendermethode, sodass sie nur einmal erstellt wird, sodass das Rendering immer dieselbe EnhancedComponent zurückgibt.

Mutieren Sie die verpackte Komponente nicht

Das Mutieren der umhüllten Komponente innerhalb eines HOC macht es unmöglich, die umhüllte Komponente außerhalb des HOC zu verwenden. Wenn Ihr HOC eine WrappedComponent zurückgibt, können Sie fast immer sicher sein, dass Sie es falsch machen. Das folgende Beispiel zeigt den Unterschied zwischen Mutation und Zusammensetzung.

Die Zusammensetzung ist eine der grundlegenden Eigenschaften von React. Sie können eine Komponente in ihrer Renderfunktion in eine andere Komponente einbinden lassen, und das nennen Sie Komposition.

Wenn Sie die WrappedComponent in einem HOC mutieren und dann die erweiterte Komponente mit einem anderen HOC umschließen, werden die vom ersten HOC vorgenommenen Änderungen überschrieben. Um solche Szenarien zu vermeiden, sollten Sie sich an das Erstellen von Komponenten halten, anstatt sie zu muteren.

Namespace Generische Propnames

Die Wichtigkeit von Namespace-Requisitennamen wird deutlich, wenn Sie mehrere gestapelt haben. Eine Komponente kann einen Requisitennamen in die WrappedComponent verschieben, die bereits von einer anderen Komponente höherer Ordnung verwendet wurde.

Sowohl die withMouse als auch die withCat versuchen, ihre eigene Version der Namensstütze zu veröffentlichen. Was wäre, wenn auch die EnhancedComponent enige Requisiten mit demselben Namen teilen müsste?

Wäre es nicht eine Quelle der Verwirrung und Fehlleitung für den Endentwickler? ie React DevWerkzeugs melden keine Namenskonflikte, und Sie müssen die Details der HOC-Implementierung überprüfen, um zu verstehen, was schief gelaufen ist.

Dies kann gelöst werden, indem HOC-Requisitennamen als Konvention über das HOC festgelegt werden, das sie bereitstellt. Sie hätten also withCat_name und withMouse_name anstelle eines generischen Requisitennamens.

Eine weitere interessante Sache, die Sie hier beachten sollten, ist, dass die Bestellung Ihrer Immobilien in React wichtig ist. Wenn Sie dieselbe Eigenschaft mehrmals haben, was zu einem Namenskonflikt führt, bleibt die letzte Deklaration immer erhalten. Im obigen Beispiel gewinnt die Katze, da sie nach { ...this.props } platziert ist.

Wenn Sie den Namenskonflikt lieber auf andere Weise lösen möchten, können Sie die Eigenschaften neu anordnen und this.props zuletzt verbreiten. Auf diese Weise können Sie sinnvolle Standardeinstellungen festlegen, die zu Ihrem Projekt passen.

Erleichtern Sie das Debuggen mit einem aussagekräftigen Anzeigenamen

Die von einem HOC erstellten Komponenten werden in den React DevWerkzeugs als normale Komponenten angezeigt. Es ist schwer zwischen den beiden zu unterscheiden. Sie können das Debuggen vereinfachen, indem Sie einen aussagekräftigen displayName für die Komponente höherer Ordnung angeben. Wäre es nicht sinnvoll, so etwas auf React DevWerkzeugs zu haben?

Was ist also displayName? Jede Komponente verfügt über eine displayName-Eigenschaft, die Sie zum Debuggen verwenden können. Die beliebteste Technik ist das Umschließen des Anzeigenamens der WrappedComponent. Wenn withCat das HOC und NameComponent die WrappedComponent ist, lautet der displayName withCat (NameComponent).

Eine Alternative zu Komponenten höherer Ordnung

Obwohl Mixins weg sind, wäre es irreführend zu sagen, dass Komponenten höherer Ordnung das einzige Muster sind, das Code-Sharing und Abstraktion ermöglicht. Ein anderes alternatives Muster ist aufgetaucht, und ich habe einige sagen hören, es sei besser als HOCs. Es würde den Rahmen dieses Tutorials sprengen, das Konzept ausführlich zu behandeln, aber ich werde Ihnen das Rendern von Requisiten und einige grundlegende Beispiele vorstellen, die zeigen, warum sie nützlich sind.

Render Requisiten werden mit verschiedenen Namen bezeichnet:

  • Render-Prop
  • Kinderstütze
  • Funktion als Kind
  • Rückruf rendern

Hier ist ein kurzes Beispiel, das erklären soll, wie eine Render-Requisite funktioniert.

Wie Sie sehen können, haben wir die Funktionen höherer Ordnung beseitigt. Wir haben eine reguläre Komponente namens Mouse. Anstatt eine umschlossene Komponente in ihrer Rendermethode zu rendern, werden wir this.props.children() rendern und den Status als Argument übergeben. Also geben wir Mouse eine Render-prop und die Render-Requisite entscheidet, was gerendert werden soll.

Mit anderen Worten, die Mouse komponenten akzeptieren eine Funktion als Wert für die untergeordneten Requisiten. Beim Rendern der Mouse wird der Status der Mouse zurückgegeben, und die Render-Prop-Funktion kann ihn nach Belieben verwenden.

Es gibt ein paar Dinge, die ich an diesem Muster mag:

  • Aus Sicht der Lesbarkeit ist es offensichtlicher, woher eine Requisite kommt.
  • Dieses Muster ist dynamisch und flexibel. HOCs werden zur statischen Zeit zusammengesetzt. Obwohl ich nie festgestellt habe, dass dies eine Einschränkung darstellt, sind Render-Requisiten dynamisch zusammengesetzt und flexibler.
  • Vereinfachte Zusammensetzung der Komponenten. Sie können sich vom Verschachteln mehrerer HOCs verabschieden.

Abschluss

Komponenten höherer Ordnung sind Muster, mit denen Sie robuste, wiederverwendbare Komponenten in React erstellen können. Wenn Sie HOCs verwenden möchten, sollten Sie einige Grundregeln befolgen. Dies ist so, dass Sie die Entscheidung, sie später zu verwenden, nicht bereuen. Ich habe die meisten Best Practices in diesem Tutorial zusammengefasst.

HOCs sind nicht die einzigen Muster, die heute beliebt sind. Gegen Ende des Tutorials habe ich Ihnen ein anderes Muster vorgestellt, das als Render-Requisiten bezeichnet wird und unter den React-Entwicklern an Boden gewinnt.

Ich werde kein Muster beurteilen und sagen, dass dieses besser ist als das andere. Wenn React wächst und das Ökosystem, das es umgibt, reift, entstehen immer mehr Muster. Meiner Meinung nach sollten Sie sie alle lernen und sich an die halten, die zu Ihrem Stil passt und mit der Sie sich wohl fühlen.

Dies markiert auch das Ende der Lernserie zu Komponenten höherer Ordnung. Wir sind vom Nullpunkt zum Erlernen einer fortschrittlichen Technik namens HOC übergegangen. Wenn ich etwas verpasst habe oder wenn Sie Vorschläge/Gedanken haben, würde ich sie gerne hören. Sie können sie in den Kommentaren posten.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.