Dies ist eine Fortsetzung des vorherigen Artikels: Warum sollten Sie Ihr React Data Grid 2019 schreiben?
Wofür ist Redux? Es gibt viele Antworten. Zum Beispiel, um mit gemeinsam genutzten Daten in verschiedenen React-Komponenten zu arbeiten. Sie können jedoch Redux verwenden, um eine Komponente zu manipulieren. Das Aussehen selbst ist interessant: Jede React-Komponente kann über Redux eine andere React-Komponente steuern.
Nehmen Sie eine React-Komponente, die Daten in Form von Zeilen und Spalten (Datenraster, Raster) anzeigt. Welche Funktionen kann sie verwalten? Die Zusammensetzung der Spalten und Zeilen. Zuordnung. Es wäre schön, die Daten zu scrollen.

Beispielsweise könnte eine bestimmte Reaktionskomponente (eine Komponente) das Raster folgendermaßen verwalten:
- solche Zeilen und Spalten anzeigen;
- das Auftreten eines solchen Wortes hervorheben;
- wähle eine solche Linie aus;
- zu einer bestimmten Zeile scrollen.
Das Verwalten von Spalten ist nicht schwierig. Es reicht aus, die Spalteneinstellungen in Redux zu setzen: Namen, Reihenfolge, Breiten, Datenzuordnung. Das Raster übernimmt diese Einstellungen und wird angewendet. Der Datenansatz ist der gleiche.
Aber lassen Sie uns die Aufgabe komplizieren. Angenommen, es gibt viele Zeilen. Sie können nicht sofort vom Server heruntergeladen und nicht sofort angezeigt werden. Daher sind das Laden portionierter Daten und die Zuordnung portionierter Daten erforderlich.
Für die Portionsanzeige verwenden wir das im vorherigen Artikel beschriebene virtuelle Scrollen. Und versuchen Sie es mit Portionsladen und Lagerung in Redux zu überqueren. Wir werden auch anderen Komponenten ermöglichen, heruntergeladene Daten zu bearbeiten und die Position durch Redux zu scrollen.
Dies ist keine abstrakte Aufgabe, sondern eine echte Aufgabe des ECM-Systems, das wir entwickeln:

Ordnen Sie die Anforderungen. Was willst du bekommen?
- so dass beim Scrollen neue Daten geladen werden;
- so dass die geladenen Daten in Redux sind;
- so dass geladene Teile von anderen Komponenten manipuliert werden können. Fügen Sie über Redux Zeilen hinzu, löschen Sie sie und ändern Sie sie, und das Raster hat diese Änderungen übernommen.
- damit die Bildlaufposition von anderen Komponenten aus gesteuert werden kann. Scrollen Sie durch Redux zur gewünschten Zeile.
Wir werden diese Aufgaben berücksichtigen.
Ein kleiner Exkurs: Mit dem virtuellen Bildlauf aus dem vorherigen Artikel können Sie schnell zu einem beliebigen Teil des Rasters scrollen. Zum Beispiel am Ende. Das Raster muss den neuesten Teil der Daten laden, mit Ausnahme aller Zwischendaten, um nicht Tausende von Zeilen vom Server zu ziehen. Daher werden Teile nicht immer nacheinander geladen, sondern können aus verschiedenen Teilen der Liste heruntergeladen werden.
Wir haben das folgende Schema zum Laden und Speichern von Daten gewählt:

Das Raster in diesem Schema ist in zwei Teile unterteilt - Komponenten Präsentation und Container. Die Präsentation befasst sich nur mit der Datenanzeige - dies ist die Ansicht. Daten werden auf Seiten angezeigt (dies wurde in einem vorherigen Artikel beschrieben). Der Container ist für das Laden der Daten und die Interaktion mit Redux verantwortlich.
Lassen Sie uns die Pfeile des Diagramms durchgehen:
- Presentational lädt keine Daten, sondern teilt nur per Rückruf mit, welche Daten nicht angezeigt werden können. Presentational kennt Redux nicht, führt keine Versandaktionen aus und stellt keine Verbindung zum Redux-Repository her.
- Der Container ist für das Laden der Daten verantwortlich. Diese Komponente sendet beim Rückruf eine Anfrage an den Server. Ein Container kann mehr Daten anfordern, als angezeigt werden müssen, um die Anzahl der Anforderungen an den Server zu minimieren.
- Der Server sendet Daten.
- Container sendet die empfangenen Daten an Redux. Redux speichert alle hochgeladenen Teile von Daten, nicht nur den zuletzt hochgeladenen Teil.
- Sobald die nächsten Daten in Redux eingehen, zieht der Container alle Teile aus Redux heraus.
- Und gib ihnen Präsentation. Presentational ist nicht erforderlich, um alle empfangenen Daten zu zeichnen. Es wird nur angezeigt, was in das Ansichtsfenster fällt. Gleichzeitig sind die geladenen Daten und die gerenderten Seiten nicht dasselbe. In einem Block können 1000 Datensätze geladen werden, und auf zwei Seiten werden 50 Datensätze angezeigt.
Hier ist der Pseudocode dieser Schaltung:
class GridContainer extends React.Component<Props> { props: Props; render(): React.Element<any> { return <Grid // . dataSource={this.props.data} // Callback . loadData={this.props.loadData} />; } }
const mapStateToProps = (state) => { return { data: state.data }; }; const mapDispatchToProps = (dispatch) => { return { loadData: async (skip: number, take: number) => {
Verwendete Typen im Pseudocode:
type Props = { data: DataSource, loadData: (skip: number, take: number) => void }; type DataSource = {
Sie haben die erste Aufgabe bewältigt - das teilweise Laden und Speichern von Daten in Redux. Kommen wir nun zur Manipulation. Die häufigste Aufgabe ist das Hinzufügen, Löschen und Ändern von Zeilen. Wir möchten, dass jede Komponente der Webanwendung dies kann. Das Schema ist einfach:

Einige Komponenten sind Komponenten einer Webanwendung, die Rasterdaten verwalten möchten.
Lassen Sie uns das Schema durchgehen:
- Alle Datenmanipulationen werden über Redux-Reduzierungen durchgeführt. Um die Zeile hinzuzufügen, zu löschen oder zu ändern, reicht es aus, die entsprechende Aktion (ADD_ROW, DELETE_ROW, UPDATE_ROW) abzugleichen. Reduzierer passen die Daten im Redux-Repository an.
- Sobald sich die Daten in Redux ändern, ruft der Grid Container die aktuellen Daten aus Redux ab.
- Und gib ihnen Präsentation. Präsentationsaktualisierungen gerenderte Seiten.
Scrollen durch Redux
Das programmgesteuerte Verwalten des Bildlaufs ist eine notwendige Funktion. Am häufigsten wird zum markierten Eintrag gescrollt. Beispielsweise erstellt der Benutzer einen neuen Eintrag in der Liste. Ein Datensatz mit Sortierung befindet sich in der Mitte der Liste. Sie müssen es programmgesteuert auswählen und dorthin scrollen. Und es wäre schön, dies über Redux zu tun.

Das Verwalten von Auswahlen über Redux ist nicht schwierig, aber wie steuern Sie das Scrollen?
Dazu werden wir im Redux Store zwei Felder einfügen:
Das scrollLoIndex-Feld ist verständlich. Wenn Sie scrollen möchten, legen Sie die Nummer der gewünschten Zeile in scrollToIndex fest. Diese Nummer wird in das Raster übertragen und das Raster wird sofort dorthin gescrollt:

Wofür ist das scrollSignal-Feld? Es löst das Problem des erneuten Bildlaufs zum gleichen Index. Wenn wir bereits einen Software-Bildlauf zum Index 100 durchgeführt haben, funktioniert der Bildlauf zum gleichen Index nicht mehr. Daher wird das scrollSignal-Feld verwendet. Wenn es geändert wird, wird das Raster erneut zu scrollToIndex gescrollt. ScrollSignal wird beim Reduzieren einer SCROLL-Aktion automatisch im Reduzierer erhöht:

Pseudo-Code für die Bildlaufsteuerung:
class GridContainer extends React.Component<Props> { props: Props; render(): React.Element<any> { return <Grid // . dataSource={this.props.data} // , .. scrollToIndex={this.props.scrollToIndex} // , . scrollSignal={this.props.scrollSignal} />; } }
const mapStateToProps = (state) => { return { data: state.data, scrollToIndex: state.scrollToIndex, scrollSignal: state.scrollSignal }; }; export default connect(mapStateToProps)(GridContainer);
Verwendete Typen im Pseudocode:
type Props = { data: DataSource, scrollToIndex: ?number, scrollSignal: number };
Fazit (von Redux)
Die vorgeschlagenen Interaktionsschemata mit Redux sind natürlich nicht universell. Sie sind für das von uns entwickelte Raster geeignet, da wir das Raster für diese Schemata optimiert und die entsprechende API dafür erstellt haben. Diese Schemata funktionieren nicht für Grids von Drittanbietern. Nehmen Sie den Artikel als ein Beispiel für die Implementierung der Interaktion mit Redux.
Endgültige Schlussfolgerung (zu Artikel 1 und 2)
Bei der Entwicklung unseres Grids wurde klar, dass das Grid im Idealfall nicht Teil unserer Anwendung ist, sondern ein unabhängiges Projekt, das auf Github gestellt und entwickelt werden sollte. Daher haben wir die Betreffbegriffe unserer Anwendung im Code nicht verwendet und unnötige Abhängigkeiten hinzugefügt. Mit der Erweiterung der Funktionalität wird es jedoch immer schwieriger, sich daran zu halten, da wir es nicht einem separaten Projekt zugewiesen haben, sondern es sofort hätten tun sollen. Github ist noch in Planung.
Das Schreiben eines eigenen Rasters war für uns die richtige Entscheidung. Wir hatten genug Zeit, um alles zu implementieren, was wir wollten (Virtualisierung, Arbeiten mit Redux, Batch-Laden, Arbeiten mit der Tastatur, Arbeiten mit Spalten, Suchen mit Hintergrundbeleuchtung und vieles mehr). Anfangs haben wir stark in ein Drittanbieter-Netz investiert, in der Hoffnung, dass es sich in unseren Situationen durchsetzen wird. Auf diese Weise haben wir verstanden, wie Grids im Allgemeinen funktionieren, welche Probleme existieren, wie sie gelöst werden können und was wir letztendlich erreichen möchten. Und traf ihre Entscheidung.