Vorwort
Dies ist mein erster Beitrag zu Habré, also urteile nicht zu hart (na ja, oder urteile, aber konstruktiv ).
Ich möchte darauf hinweisen, dass bei diesem Ansatz der Hauptvorteil für mich darin besteht, dass wir die Geschäftslogik klar nach Modulen abgrenzen und delegieren. Ein Modul ist für eine Sache und für etwas sehr Spezifisches verantwortlich. Das heißt, bei diesem Ansatz gibt es während des Entwicklungsprozesses keinen Gedanken: "Wo würde ich das hier besser (genauer) tun?" Mit diesem Ansatz ist sofort klar, wo genau die Aufgabe / das Problem gelöst werden soll.
Dateistruktur
Projektstruktur + ist Standard. Ich werde versuchen, Ihnen kurz zu sagen, woraus die Baugruppe selbst besteht
- Um asynchrone Aktionen vorzubereiten, verwende ich Saga-Middleware - eine viel flexiblere und leistungsfähigere Sache in Bezug auf Thunk-Middleware
- Ich habe CSS-Module Styling-Komponenten. Tatsächlich ist das Konzept das gleiche wie das von gestalteten Komponenten, aber irgendwie ist es für mich bequemer
- Eine Zwischenschicht zwischen Containern und Komponenten, die die aus dem Geschäft in die Komponente geworfenen Requisiten steuert (Filterung, Memoisierung und die Möglichkeit, die Feldnamen eines beliebigen Anwendungsstatus bequem zu bearbeiten) - Neuauswahl
Redux-Sagen
Dokumentation von Redux-Sagas
Das Wesentliche an Sagas (und nicht nur) ist, dass wir die Geschäftslogik der Arbeit mit Anforderungen nach Modulen trennen. Jede Saga ist für ihren eigenen Teil der API verantwortlich. Wenn ich Benutzerdaten abrufen und eine Aktion nach deren erfolgreichem Empfang aufrufen müsste, würde ich dies in einem separaten Modul tun. UsersSagas.js
Die Hauptfaktoren (für mich) für die Sagen sind:
UPD (ein Punkt über Versprechen-Hölle hinzugefügt)
- 1) Die Tatsache, dass Handlungen auf gütliche Weise nur Funktionen sein sollten, die ein Objekt ergeben. Wenn einige der Aktionen anders aussehen (und so passiert es mit der Verwendung von Thunk), möchte ich sie irgendwie in eine Form bringen, weil dies irgendwie nicht in ein einzelnes Konzept passt. Ich möchte die Logik von Anfragen verschieben und mit Daten für Anfragen in ein separates Modul arbeiten - dafür sind Sagen gedacht
- 2) Wenn wir mehrere Anforderungen stellen müssen, die Daten aus Antworten auf frühere Anforderungen verwenden (und keine Zwischendaten im Speicher speichern möchten?), Lädt Redux-thunk uns in der Regel ein, eine neue Aktion auszuführen, in der wir eine andere aufrufen asynchrone Aktionsanforderung, bei der 2 weitere (zum Beispiel) dieselben Iterationen durchgeführt werden. Es riecht nach Versprechen-Hölle und sieht normalerweise chaotisch und im Prinzip unpraktisch aus (zu viele Verschachtelungen), wie für mich
CSS-Module / gestaltete Komponenten
Bei Projekten sehe ich oft, dass Leute Regeln für das Styling von Komponenten in einigen gängigen CSS-Modulen schreiben.
Ich bin total dagegen. Die Komponente ist ein isoliertes System. Es sollte so wiederverwendbar wie möglich sein . Daher wäre es schön, es separat zu stylen.
Neu auswählen
Selektoren haben mehrere Ziele:
- , . , , ( , ). , , . - getFilteredItems,
- ,
- . - . - . friends. , . , . , , friends contacts. reselect , , . — .
Es ist wegen des letzten Punktes, dass ich ertrinke, weil wir bei jedem Niesen einen Reset machen. Neu auswählen - nicht nur zum Auswendiglernen, sondern auch zum bequemeren Arbeiten mit dem Zeichnen des Anwendungsstatusbaums
Komponenten und Behälter
Beim klassischen React-Ansatz (ohne Verwendung von Bibliotheken zum Speichern des Speichers als separate Entität) gibt es zwei Arten von Komponenten: Präsentations- und Containerkomponenten. Normalerweise (so wie ich es verstehe) ist dies keine strikte Ordneraufteilung, sondern eine konzeptionelle Aufteilung.
Präsentationskomponenten sind dumm. Sie sind in der Tat nur das Layout und die Anzeige von Daten, die als Requisiten in sie geworfen wurden. (Ein Beispiel für eine solche Komponente finden Sie oben in CSS-Modulen.)
Container-Komponenten - Komponenten, die die Logik der Arbeit mit beispielsweise dem Lebenszyklus einer Komponente kapseln. Sie sind dafür verantwortlich, eine Aktion aufzurufen, die beispielsweise für die Anforderung von Daten verantwortlich ist. Sie geben ein Minimum an Layout zurück, da das Layout in Presentational-Components isoliert ist.
Beispiel + -Behälterkomponente:
Redux-Behälter sind in der Tat eine Schicht zwischen der Redax-Seite und den Reaktionskomponenten. In ihnen rufen wir Selektoren auf und werfen Aktionen in die Reaktionsstützen der Komponente.
ICH BIN FÜR für jeden Nieser seinen eigenen Behälter mit. Erstens erhalten Sie mehr Kontrolle über die in die Komponente geworfenen Requisiten, und zweitens erhalten Sie mithilfe von Reselect Kontrolle über die Leistung.
Es kommt oft vor, dass wir eine Komponente wiederverwenden müssen, jedoch mit unterschiedlichen Teilen des Geschäfts. Es stellt sich heraus, dass wir dafür nur einen weiteren Container schreiben und ihn gegebenenfalls zurückgeben müssen. Das heißt, die Beziehung Viele zu Eins (viele sind Container, einer ist eine Komponente. Für mich ist es bequem und konzeptionell)
Ich möchte auch ein häufigeres Beispiel für die Containerisierung der meisten Komponenten geben.
Wir haben ein Array von Daten (zum Beispiel ein Array von Benutzern), die wir von einer API erhalten. Wir haben auch eine unendliche Schriftrolle, die der Kunde nicht ablehnen wird. Wir haben sehr lange nach unten gescrollt und über 10.000 Daten geladen. Und jetzt haben wir einige Eigenschaften eines Benutzers geändert. Unsere Anwendung wird sich sehr verlangsamen, weil:
- Wir haben den globalen Container mit der Liste der Benutzer an die gesamte Seite angehängt
- Wenn Sie ein Feld eines Elements des Benutzerarrays ändern, wird im Benutzerreduzierer ein NEUES Array mit neuen Elementen und Indizes zurückgegeben
- Alle Komponenten, die im Baum der UsersPage-Komponente platziert sind, werden neu gezeichnet. Einschließlich jeder Benutzerkomponente (Array-Element)
Wie können Sie das vermeiden?
Wir machen Container auf
- Array mit Benutzern
- Array-Element (ein Benutzer)
Danach geben wir in der Komponente, die in einen Container "Array mit Benutzern" eingeschlossen ist, den Container "Array-Element (ein Benutzer)" mit dem dort geworfenen Schlüssel (Reaktion erforderlich Prop) zurück, index.
Im Container "Array-Element (ein Benutzer)" in mapStateToProps sind wir der zweite Als Argument nehmen wir die ownProps der Komponente, die der Container zurückgibt (darunter Index). Nach Index ziehen wir nur ein Element des Arrays direkt aus dem Speicher.
Außerdem wird es viel einfacher, das Neuzeichnen nur des geänderten Elements zu optimieren (das gesamte Array wird neu gezeichnet, da wir im Reduzierer eine Art Map erstellt haben, die ein NEUES Array mit neuen Indizes für jedes Element zurückgibt ). Hier wird uns durch die erneute
Auswahl des Container-Arrays geholfen :
das Container-Element:
Elementauswahl:
Wenn es Ergänzungen gibt, werde ich sie gerne in den Kommentaren lesen.