Ist es ohne Redux möglich?

Heute finden Sie viele Positionen, an denen Reagieren / Reduzieren erforderlich ist. Die Reaktion ist großartig, keine Fragen gestellt. Die Frage für Redux ist, ob es ohne es möglich ist. Wenn Sie ein wenig googeln, gibt es einen soliden Artikel über Habré , in dem der Autor dieselbe Frage stellt. In einem Artikel mit einem einfachen Beispiel (todoList) wird die Methode this.updateViews () zu oft (sieben bis acht Mal) aufgerufen, und dies scheint einfacher zu sein.

Die Hauptidee hier sind beobachtbare Modelle, reagieren ist verantwortlich für beobachtbar, das einzige, was übrig bleibt, ist ein Modell zu erstellen.

Bevor Sie das Modell erstellen, einige Worte zum Design (Architektur) des Clients:

Index - Rohdaten
Geschichte - Array [Modell]
Beobachter - Modell
Ansicht - Fehler, Fokus, Flags

index.jsx - Programmeinstiegspunkt für den Benutzerbildschirm. Index rendert alle Komponenten mit Standarddaten, führt asynchrone Abfragen durch und zeichnet Komponenten mit neuen Daten neu.

// index.jsx <History> <Observer> <HeaderView /> <MainView /> </Observer> </History> 

Observer.jsx ist für die Synchronisierung des Modells für mehrere Ansichten verantwortlich. Zum Beispiel füllt Petya ein Angebotsformular aus und sieht eine Echtzeitvorschau im Seitenkopf. Observer speichert das Modellobjekt und stellt den untergeordneten Komponenten api: onModelChange (Feld, Wert) zur Verfügung.

History.jsx ist ein Stapel von Modellobjekten, wobei api: commit und rollback.

Model.js kann der Benutzer mit Stiften eingeben - das ist das Wertvollste. Andere Daten im Modell müssen nicht gespeichert werden. Das Modell ist keine Reaktionskomponente, sondern eine reguläre js-Klasse.

 class Model { constructor(other = {}) {} // copy constructor (and default too) isEqual(other) {} // operator == less(other) {} // operator< swap(other) {} hash() {} fieldNameConstrains() {} //see below please } 

Der Kopierkonstruktor wird mindestens für den Verlauf benötigt. Die isEqual-Methode ist für nicht gespeicherte Popup-Änderungen vorgesehen (was viel praktischer ist als das Flag im Status). Die fieldNameConstrains-Methode gilt für abhängige Felder.

Grob gesagt, wenn es abhängige Felder gibt, müssen sie alle hintereinander geändert werden.

 class Model { // constrains // distance <== velocity * time velocityConstrains(newVelocity) { this.velocity = newVelocity; this.distance = this.velocity * this.time; } timeConstrains(newTime) { … } distanceConstrains(newDistance) { this.distance = newDistance; this.time = this.distance / this.velocity; } } 

Aus persönlicher Erfahrung funktioniert so etwas wie model.field.onchange nicht, da Sie manchmal den Kopierkonstruktor aufrufen müssen und onchange-Ereignisse überhaupt nicht benötigt werden.

View.jsx

 class View extends React.Component { state = { errors: {}, focus: {}, … } render() { … <input value={this.props.model.title} onChange={e => this.props.onModelChange('title', e.target.value)} /> … } } 

Validierung Die Validierung muss im Modell nicht durchgeführt werden. Dies muss in der Ansicht erfolgen (vergessen Sie nicht, dass die Ansicht der Bildschirm des Benutzers ist und nicht das gesamte Modell auf dem Bildschirm angezeigt werden kann). Validatoren sind eine Reihe von Prädikaten. Es gibt nur zwei Algorithmen zur Validierung: 1) Wir finden alle Fehler in der Form oder 2) Wir finden den ersten Fehler. Zum Beispiel

 class View extends React.Component { onClickSaveButton() { const mapper = { title: () => model.title.length && !maxLenValidator(model.title, 25), price: () => !(model.price % 40 == 0), url: () => !urlValidator(model.url), … } const errors = map(mapper, (validator, key) => { return validator() ? key : undefined; }).filter(Boolean); } //       

Zugangsrechte. Die Hauptsache hier ist, zu bleiben und keine Vererbung zu verwenden. Die Idee ist, dass das Modell alle Felder enthält und wir die Felder für Rollen zuschneiden. Das heißt, es handelt sich um eine Whitelist. Die verbleibenden Felder im Modell bleiben standardmäßig erhalten. Ein Schritt wird zur Validierung hinzugefügt - wir machen eine Projektion des Validierungsobjekts (es ist auch Mapper, siehe oben), dh wir validieren nur die erforderlichen Felder.

Über die Produktion. Dieser Ansatz dreht sich seit einem Jahr in der Produktion - er ist eine Schnittstelle für die Erstellung von Werbekampagnen, einschließlich Bannern. Formen unterschiedlicher Komplexität - von einem Modell bis zum Bildschirm, die mit vielen Modellen unterschiedlicher Typen enden. Hier können Sie hinzufügen, dass das Backend gerne verschachtelte Strukturen sendet. Sie sollten nicht schüchtern sein und nur flache Strukturen in der Ansicht speichern.

Informationen zur isEqual-Modellmethode. Irgendwo in utils.js wird es die Methoden isEqual und isEqualArray geben:

  function isEqual(left, right) { return left.isEqual(right); } isEqualArray(v1, v2) { if (v1.length !== v2.length) { return false } for (var k = 0; k != v1.length; k++) { if (!isEqual(v1[k], v2[k])) { return false; } } return true; } 

Sie müssen versuchen, keine verschachtelten Modelle zu erstellen. Vergessen Sie nicht, dass das Modell Benutzerdaten sind, keine Datenstruktur.

Referenzen:

Zeiten
Zwei

Source: https://habr.com/ru/post/de455176/


All Articles