Dies ist eine Mischung aus einer unendlichen Tabelle und einem unendlichen Bildlaufszenario. Die beste Abstraktion, die ich dafür gefunden habe, ist die folgende:
Überblick
Erstellen Sie eine <List>
Komponente, die ein Array aller untergeordneten Elemente enthält. Da wir sie nicht rendern, ist es wirklich billig, sie einfach zuzuweisen und zu verwerfen. Wenn 10.000 Zuordnungen zu groß sind, können Sie stattdessen eine Funktion übergeben, die einen Bereich annimmt, und die Elemente zurückgeben.
<List>
{thousandelements.map(function() { return <Element /> })}
</List>
Ihre List
Komponente verfolgt die Bildlaufposition und rendert nur die angezeigten untergeordneten Elemente. Am Anfang wird ein großes leeres Div hinzugefügt, um die vorherigen Elemente zu fälschen, die nicht gerendert wurden.
Der interessante Teil ist nun, dass Element
Sie nach dem Rendern einer Komponente ihre Höhe messen und in Ihrer speichern List
. Auf diese Weise können Sie die Höhe des Abstandshalters berechnen und wissen, wie viele Elemente in der Ansicht angezeigt werden sollen.
Bild
Sie sagen, dass beim Laden des Bildes alles nach unten "springt". Die Lösung hierfür besteht darin, die Bildabmessungen in Ihrem img-Tag festzulegen : <img src="..." width="100" height="58" />
. Auf diese Weise muss der Browser nicht warten, um ihn herunterzuladen, bevor er weiß, welche Größe angezeigt wird. Dies erfordert eine gewisse Infrastruktur, aber es lohnt sich wirklich.
Wenn Sie die Größe nicht im Voraus kennen, fügen Sie onload
Ihrem Bild Listener hinzu. Wenn es geladen ist, messen Sie die angezeigte Abmessung, aktualisieren Sie die gespeicherte Zeilenhöhe und kompensieren Sie die Bildlaufposition.
Auf ein zufälliges Element springen
Wenn Sie auf ein zufälliges Element in der Liste springen müssen, erfordert dies einige Tricks mit der Bildlaufposition, da Sie die Größe der dazwischen liegenden Elemente nicht kennen. Ich empfehle Ihnen, die bereits berechneten Elementhöhen zu mitteln und zur Bildlaufposition der letzten bekannten Höhe + (Anzahl der Elemente * Durchschnitt) zu springen.
Da dies nicht genau ist, wird es Probleme verursachen, wenn Sie zur letzten bekannten guten Position zurückkehren. Wenn ein Konflikt auftritt, ändern Sie einfach die Bildlaufposition, um ihn zu beheben. Dies wird die Bildlaufleiste ein wenig verschieben, sollte ihn / sie jedoch nicht zu sehr beeinträchtigen.
Reaktionsspezifikationen
Sie möchten allen gerenderten Elementen einen Schlüssel zur Verfügung stellen , damit sie über das Rendern hinweg beibehalten werden. Es gibt zwei Strategien: (1) haben nur n Tasten (0, 1, 2, ... n), wobei n die maximale Anzahl von Elementen ist, die Sie anzeigen und deren Positionsmodulo n verwenden können. (2) haben einen anderen Schlüssel pro Element. Wenn alle Elemente eine ähnliche Struktur haben, empfiehlt es sich, (1) zu verwenden, um ihre DOM-Knoten wiederzuverwenden. Wenn nicht, verwenden Sie (2).
Ich hätte nur zwei Teile des React-Status: den Index des ersten Elements und die Anzahl der angezeigten Elemente. Die aktuelle Bildlaufposition und die Höhe aller Elemente werden direkt angehängt this
. Bei der Verwendung führen setState
Sie tatsächlich eine erneute Wiedergabe durch, die nur dann erfolgen sollte, wenn sich der Bereich ändert.
Hier ist ein Beispiel für eine unendliche Liste mit einigen der Techniken, die ich in dieser Antwort beschreibe. Es wird eine Arbeit sein, aber React ist definitiv ein guter Weg, um eine unendliche Liste zu implementieren :)
Schauen Sie sich http://adazzle.github.io/react-data-grid/index.html# an. Dies sieht aus wie ein leistungsstarkes und leistungsfähiges Datagrid mit Excel-ähnlichen Funktionen und verzögertem Laden / optimiertem Rendern (für Millionen von Zeilen) mit umfangreiche Bearbeitungsfunktionen (MIT-lizenziert). Noch nicht in unserem Projekt ausprobiert, wird es aber bald tun.
Eine großartige Ressource für die Suche nach solchen Dingen ist auch http://react.rocks/ In diesem Fall ist eine Tag-Suche hilfreich: http://react.rocks/tag/InfiniteScroll
quelle
Ich stand vor einer ähnlichen Herausforderung bei der Modellierung des unendlichen Bildlaufs in einer Richtung mit heterogenen Elementhöhen und machte aus meiner Lösung ein npm-Paket:
https://www.npmjs.com/package/react-variable-height-infinite-scroller
und eine Demo: http://tnrich.github.io/react-variable-height-infinite-scroller/
Sie können den Quellcode für die Logik überprüfen, aber ich habe im Grunde das Rezept @Vjeux befolgt, das in der obigen Antwort beschrieben ist. Ich habe mich noch nicht mit dem Springen zu einem bestimmten Gegenstand befasst, aber ich hoffe, dass ich das bald umsetzen kann.
Hier ist das Wesentliche, wie der Code derzeit aussieht:
quelle