5 Best Practices für React Architecture für 2021

Blog

5 Best Practices für React Architecture für 2021

Die Originaler Artikel ist zu finden auf https://www.sitepoint.com



Es besteht kein Zweifel, dass React die Art und Weise, wie wir Benutzeroberflächen erstellen, revolutioniert hat. Es ist leicht zu erlernen und erleichtert die Erstellung wiederverwendbarer Komponenten, die Ihrer Website ein einheitliches Erscheinungsbild verleihen.

Da sich React jedoch nur um die Ansichtsschicht einer Anwendung kümmert, erzwingt es keine bestimmte Architektur (wie MVC oder MVVM). Dies kann es schwierig machen, Ihre Codebasis zu organisieren, wenn Ihr React-Projekt wächst.



Bei 9Elemente , eines unserer Flaggschiff-Produkte ist PhotoEditorSDK — ein vollständig anpassbarer Fotoeditor, der sich leicht in Ihre HTML5-, iOS- oder Android-App integrieren lässt. PhotoEditorSDK ist eine groß angelegte React-App für Entwickler. Es erfordert hohe Leistung, kleine Builds und muss in Bezug auf das Styling und insbesondere das Thema sehr flexibel sein.

Während der vielen Iterationen von PhotoEditorSDK haben mein Team und ich eine Reihe von Best Practices für die Organisation einer großen React-App gesammelt, von denen wir einige in diesem Artikel mit Ihnen teilen möchten.



  • Verzeichnis-Layout
  • CSS in JavaScript
  • Benutzerdefinierte Haken
  • Funktion als Kinder
  • Requisiten rendern

1. Verzeichnis-Layout

Ursprünglich waren das Styling und der Code für unsere Komponenten getrennt. Alle Stile lebten in einer gemeinsamen CSS-Datei (wir verwenden SCSS für die Vorverarbeitung). Die eigentliche Komponente (in diesem Fall |_+_|) wurde von den Stilen entkoppelt:

FilterSlider

Bei mehreren Refactorings haben wir festgestellt, dass dieser Ansatz nicht sehr gut skaliert. In Zukunft müssten unsere Komponenten von mehreren internen Projekten wie dem SDK und einem experimentellen Texttool, das wir derzeit entwickeln, gemeinsam genutzt werden. Also wechselten wir zu einem komponentenzentrierten Dateilayout:

├── components │ └── FilterSlider │ ├── __tests__ │ │ └── FilterSlider-test.js │ └── FilterSlider.jsx └── styles └── photo-editor-sdk.scss

Die Idee war, dass sich der gesamte Code, der zu einer Komponente gehört (wie JavaScript, CSS, Assets, Tests) in einem einzigen Ordner befindet. Dadurch ist es sehr einfach, den Code in ein npm-Modul zu extrahieren oder, falls es mal eilig ist, den Ordner einfach mit einem anderen Projekt zu teilen.

Rubin auf Schienen Architektur

Komponenten importieren

Einer der Nachteile dieser Verzeichnisstruktur besteht darin, dass Sie zum Importieren von Komponenten den vollständig qualifizierten Pfad importieren müssen, wie folgt:

components └── FilterSlider ├── __tests__ │ └── FilterSlider-test.js ├── FilterSlider.jsx └── FilterSlider.scss

Aber was wir wirklich gerne schreiben würden, ist folgendes:

import FilterSlider from 'components/FilterSlider/FilterSlider'

Um dieses Problem zu lösen, können Sie ein |_+_| . erstellen und exportieren Sie sofort die Standardeinstellung:

import FilterSlider from 'components/FilterSlider'

Eine andere Lösung ist etwas umfangreicher, verwendet jedoch einen Node.js-Standardauflösungsmechanismus, was sie grundsolide und zukunftssicher macht. Alles, was wir tun, ist ein |_+_| . hinzuzufügen Datei in die Dateistruktur:

index.js

Und innerhalb von |_+_| verwenden wir das Haupteigentum um unseren Einstiegspunkt auf die Komponente zu setzen, wie folgt:

export { default } from './FilterSlider';

Mit diesem Zusatz können wir eine Komponente wie diese importieren:

package.json

2. CSS in JavaScript

Das Styling und vor allem das Thematisieren war schon immer ein kleines Problem. Wie oben erwähnt, hatten wir in unserer ersten Iteration der App eine große CSS-Datei (SCSS), in der alle unsere Klassen lebten. Um Namenskollisionen zu vermeiden, verwendeten wir ein globales Präfix und folgten dem WELL-Konventionen um CSS-Regelnamen zu erstellen. Als unsere Anwendung wuchs, skalierte dieser Ansatz nicht sehr gut, also suchten wir nach einem Ersatz. Zuerst haben wir ausgewertet CSS-Module , aber zu dieser Zeit hatten sie einige Leistungsprobleme. Auch das Extrahieren des CSS über Webpacks Text-Plugin extrahieren hat nicht so gut funktioniert (obwohl es zum Zeitpunkt des Schreibens in Ordnung sein sollte). Darüber hinaus führte dieser Ansatz zu einer starken Abhängigkeit von Webpack und machte das Testen ziemlich schwierig.

Als nächstes haben wir einige der anderen CSS-in-JS-Lösungen evaluiert, die kürzlich auf den Markt gekommen sind:

Die Auswahl einer dieser Bibliotheken hängt stark von Ihrem Anwendungsfall ab:

  • Benötigen Sie die Bibliothek, um eine kompilierte CSS-Datei für die Produktion auszuspucken? EmotionJS und Linaria können das! Linaria benötigt nicht einmal eine Laufzeit. Es ordnet Requisiten CSS über . zu CSS-Variablen , was die IE11-Unterstützung ausschließt – aber wer braucht schon IE11?
  • Muss es auf dem Server laufen? Kein Problem für aktuelle Versionen aller Bibliotheken!

Für die Verzeichnisstruktur legen wir alle Styles gerne in ein |_+_|:

components └── FilterSlider ├── __tests__ │ └── FilterSlider-test.js ├── FilterSlider.jsx ├── FilterSlider.scss └── package.json

Auf diese Weise können auch reine Frontend-Leute einige Stile bearbeiten, ohne sich mit React auseinanderzusetzen, müssen jedoch minimales JavaScript lernen und das Zuordnen von Requisiten zu CSS-Attributen:

package.json

Es empfiehlt sich, Ihre Hauptkomponentendatei von HTML zu entrümpeln.

Streben nach der Einzelverantwortung der React-Komponenten

Wenn Sie hochabstrakte UI-Komponenten entwickeln, ist es manchmal schwierig, die Bedenken zu trennen. An manchen Stellen benötigt Ihre Komponente eine bestimmte Domänenlogik aus Ihrem Modell, und dann wird es chaotisch. In den folgenden Abschnitten möchten wir Ihnen einige Methoden zum TROCKNEN Ihrer Komponenten aufzeigen. Die folgenden Techniken überschneiden sich in der Funktionalität, und die Auswahl der richtigen für Ihre Architektur ist eher eine Vorliebe für den Stil als auf harten Fakten. Aber lassen Sie mich zuerst die Anwendungsfälle vorstellen:

  • Wir mussten einen Mechanismus einführen, um mit Komponenten umzugehen, die für den eingeloggten Benutzer kontextbewusst sind.
  • Wir mussten eine Tabelle mit mehreren zusammenklappbaren |_+_| . rendern Elemente.
  • Wir mussten je nach Status unterschiedliche Komponenten anzeigen.

Im folgenden Abschnitt zeige ich verschiedene Lösungen für die oben beschriebenen Probleme.

3. Benutzerdefinierte Haken

Manchmal müssen Sie sicherstellen, dass eine React-Komponente nur angezeigt wird, wenn sich ein Benutzer bei Ihrer Anwendung angemeldet hat. Zu Beginn führen Sie beim Rendern einige Plausibilitätsprüfungen durch, bis Sie feststellen, dass Sie sich häufig wiederholen. Auf deiner Mission, diesen Code zu TROCKNEN, musst du früher oder später schreiben benutzerdefinierte Haken . Keine Angst: So schwer ist es nicht. Schauen Sie sich das folgende Beispiel an:

{ 'main': 'FilterSlider.jsx' }

Die |_+_| Hook prüft, ob ein Benutzer angemeldet ist und leitet ansonsten auf eine andere Seite um. Die Logik im |_+_| Haken kann gestellt werden über Kontext oder ein staatliches Managementsystem wie MobX oder Redux .

4. Funktion als Kinder

Das Erstellen einer reduzierbaren Tabellenzeile ist keine sehr einfache Aufgabe. Wie rendern Sie die Schaltfläche zum Zusammenklappen? Wie werden die Kinder angezeigt, wenn die Tabelle nicht zugeklappt ist? Ich weiß, dass die Dinge mit JSX 2.0 viel einfacher geworden sind, da Sie ein Array anstelle eines einzelnen Tags zurückgeben können, aber ich werde dieses Beispiel erweitern, da es einen guten Anwendungsfall für die . veranschaulicht Funktion als Kinder Muster. Stellen Sie sich folgende Tabelle vor:

import FilterSlider from 'components/FilterSlider'

Und ein zusammenklappbarer Tischkörper:

styles.js

Sie würden diese Komponente wie folgt verwenden:

export const Section = styled.section` padding: 4em; background: papayawhip; `;

Sie übergeben einfach eine Funktion als Kinder, die in der übergeordneten Komponente aufgerufen wird. Möglicherweise haben Sie diese Technik auch als Render-Callback oder in besonderen Fällen als Render-Prop kennengelernt.

5. Requisiten rendern

Der Begriff Render-Requisite wurde von Michael Jackson geprägt, der dies vorschlug das Komponentenmuster höherer Ordnung könnte zu 100% durch eine reguläre Komponente mit einer Render-Requisite ersetzt werden . Die Grundidee dabei ist, dass alle React-Komponenten Funktionen sind und Funktionen als Requisiten übergeben werden können. Warum also nicht React-Komponenten über Requisiten übergeben?! Einfach!

Der folgende Code versucht zu verallgemeinern, wie Daten von einer API abgerufen werden. (Bitte beachten Sie, dass dieses Beispiel nur zu Demonstrationszwecken dient. In realen Projekten würden Sie diese Abruflogik sogar in einen |_+_|-Hook abstrahieren, um sie noch weiter von der Benutzeroberfläche zu entkoppeln.) Hier ist der Code:

components └── FilterSlider ├── __tests__ │ └── FilterSlider-test.js ├── styles.js ├── FilterSlider.jsx └── index.js

Wie Sie sehen können, gibt es eine Eigenschaft namens |_+_|, die eine Funktion ist, die während des Rendering-Prozesses aufgerufen wird. Die darin aufgerufene Funktion erhält den vollständigen Zustand als Parameter und gibt JSX zurück. Betrachten Sie nun die folgende Verwendung:

Wie Sie sehen können, ist die |_+_| und |_+_| Parameter werden aus dem Zustandsobjekt destrukturiert und können verwendet werden, um die Antwort des JSX zu steuern. In diesem Fall wird die Überschrift Loading angezeigt, solange das Versprechen nicht erfüllt wurde. Es liegt an Ihnen, welche Teile des Zustands Sie an die Render-Requisite übergeben und wie Sie diese in Ihrer Benutzeroberfläche verwenden. Insgesamt handelt es sich um einen sehr leistungsfähigen Mechanismus, um allgemeines UI-Verhalten zu extrahieren. Die Funktion als Kinder Das oben beschriebene Muster ist im Grunde das gleiche Muster, bei dem die Eigenschaft |_+_| ist.

Vorteil : Seit der Requisite rendern Muster ist eine Verallgemeinerung des Funktion als Kinder Muster, nichts hindert Sie daran, mehrere Render-Requisiten auf einer Komponente zu verwenden. Zum Beispiel ein |_+_| Komponente könnte eine Render-Prop für den Header und dann eine andere für den Body erhalten.

#reagieren #javascript #web-entwicklung