Dies ist ein Dachthema, um meine Pläne für die kommende Version 2.0 von react-window
zu teilen.
Feedback wird geschätzt und berücksichtigt. Ich bitte Sie um Verständnis, wenn ich nicht in der Lage bin, alle Anfragen zu erfüllen. Ich werde versuchen, mein Bestes zu geben, um Funktionsanforderungen gegen Bundle-Größe, Laufzeitleistung und Wartungsprobleme abzuwägen.
Ich gehe davon aus, dass für ein Upgrade von Version 1 auf 2 möglicherweise erhebliche Codeänderungen erforderlich sind , von denen viele mit Code-Mods nicht automatisiert werden können. Aus diesem Grund würde ich insbesondere für Anwendungscode davon abraten, vorhandenen Code zu aktualisieren, es sei denn, Sie haben einen wichtigen Grund (z. B. benötigen Sie Unterstützung für Inhalte mit dynamischer Größe).
Ich werde auch fortfahren und die aktuellen Dokumente an die Domain
onScroll
Eine Möglichkeit zur Verwaltung der Komplexität besteht darin , die Anzahl der von der Bibliothek unterstützten Komponenten zu
SimpleList
(zuvor FixedSizeList
)List
(zuvor DynamicSizeList
)ResizeObserver
API (oder Polyfill).Grid
(zuvor VariableSizeGrid
)Eine der wichtigsten Änderungen von react-virtualized
zu react-window
war die Entscheidung, children
als Reaktionselemente (z. B. React.createElement(children, props))
) und nicht als Render-Requisiten (z. B. children(props)
).
Dafür gab es einige Gründe:
React.memo
, useMemo
, shouldComponentUpdate
), sodass ich keine eigene Caching-Abstraktion für Item-Renderer implementieren musste.react-window
ohne dass die Render-Requisite sie weitergeben muss (und ohne dass cloneElement
Aufrufe erforderlich sind).Leider gab es auch einige Nachteile:
itemData
und ein benutzerdefinierter areEqual
Vergleichsexport erforderlich waren.Nachdem ich die oben genannten Vor- und Nachteile berücksichtigt habe, habe ich mich entschlossen, auch für react-window
auf einen Render-Requisiten-Ansatz umzusteigen . Dies bedeutet, dass komplizierte Beispiele wie dieses einfacher umgeschrieben werden können:
const Example = ({ height, items, toggleItemActive, width }) => (
<List
height={height}
itemCount={items.length}
itemRenderer={({ index, key, style }) => {
const item = items[index];
return (
<div key={key} onClick={() => toggleItemActive(index)} style={style}>
{item.label} is {item.isActive ? "active" : "inactive"}
</div>
);
}}
itemSize={35}
width={width}
/>
);
Bisher unterstützten Listenkomponenten sowohl den horizontalen als auch den vertikalen Layoutmodus. Um die Implementierung und Wartung zu vereinfachen und weil der häufigste Anwendungsfall vertikale Listen sind, werde ich die Unterstützung für layout="horizontal"
entfernen.
Rasterkomponenten unterstützen weiterhin direction="RTL"
, Listen jedoch nicht (da sie nur ein vertikales Layout unterstützen). Dieser Kompromiss wird gemacht, damit Listen kleiner und einfacher zu pflegen sind.
onItemsRendered
und onScroll
RückrufänderungenListen- und Rasterkomponenten unterstützen derzeit onItemsRendered
und onScroll
Rückruf-Requisiten. Diese Rückrufe werden während der Festschreibungsphase aufgerufen (nachdem die Liste oder das Raster das Rendern abgeschlossen hat). Dies kann insofern nützlich sein, als es immer sicher ist, als Reaktion auf diese Rückrufe einen Nebeneffekt (wie die Analyseprotokollierung) auszuführen, aber es hat auch einen Nachteil: Alle scroll-synchronisierten Aktualisierungen müssen in einem zweiten ("kaskadierenden") Rendering durchgeführt werden .
In Version 2 wird der Rückruf onScroll
geändert, um dies zu beheben. Der Rückruf onScroll
wird während des Versandzyklus des Ereignisses aufgerufen, sodass alle Aktualisierungen (von React) mit der Liste oder dem eigenen Update des Rasters gestapelt werden.
Der onItemsRendered
-Rückruf wird durch eine onItemsDisplayed
-Stütze ersetzt , obwohl er während des Festschreibungszyklus weiterhin aufgerufen wird. Diese Änderung wird vorgenommen, damit die Listenkomponente die Renderleistung aggressiver optimieren kann, indem sie vor dem Rendern mit Leerlaufpriorität erstellt und experimentelle APIs wie das Sperren von Anzeigen verwendet werden .
Es gibt mehrere ausstehende Abschreibungen (mit DEV-Warnungen), die entfernt werden:
innerTagName
und outerTagName
für alle Listen- und Rasterkomponenten. (Verwenden Sie stattdessen innerElementType
und outerElementType
.)overscanCount
, overscanColumnsCount
und overscanRowsCount
für die Rasterkomponente. (Verwenden Sie stattdessen overscanColumnCount
und overscanRowCount
.)overscanCount
wird für Listenkomponenten zugunsten eines dynamischen Overscan-Ansatzes entfernt.direction
. (Diese wurden auf layout
verschoben, werden jedoch in Version 2 vollständig entfernt.)itemData
-Stütze (und die entsprechende data
-Stütze, die an Element-Renderer übergeben wurde) werden entfernt, da die Änderung an einer Render-Requisiten-API dies nicht mehr erforderlich macht.useIsScrolling
-Stütze (und die entsprechende isScrolling
-Stütze, die an Element-Renderer übergeben wurde) werden entfernt, da die Änderungen an Vor-Rendering und Anzeigesperrung die Implementierung verteuern würden.Beachten Sie, dass einige der oben genannten veralteten Requisiten angesichts der anderen geplanten Änderungen möglicherweise noch nicht relevant sind, ich sie jedoch der Vollständigkeit halber hier aufführe.
Horizontale Listen werden in unserem Fall häufig auf Mobilgeräten verwendet. Wir verwenden sie auch für die Steuerung mit unendlich scrollbaren Karussells. IMO muss etwas auf dem Handy haben.
Vielen Dank, dass Sie einen Anwendungsfall @istarkov geteilt haben. Es ist nicht so, dass ich nicht glaube, dass es _jede_ gültige Anwendungsfälle für horizontale Fenster gibt. Ich denke nur, dass sie weit weniger verbreitet sind. (Selbst im Fall von Karussells verwenden viele die Links- / Rechtspfeilnavigation, für die kein ereignisbasiertes "Scrollen" -Fenster erforderlich ist.) Ich denke, es ist immer noch die bessere Route (für mich), die Unterstützung für Version 2 einzustellen, um einige zu kompensieren von der Komplexität, die ich mit Pre-Rendering, dynamischer Dimensionierung usw. einführen möchte.
Ich freue mich sehr über diesen schlankeren Ansatz, der hoffentlich zu einfacherem, leistungsfähigerem und einfacherem Code führen wird.
Groß. Ich habe jedoch nur wenige Bedenken, eine Liste mit variabler Größe zu löschen. Sie planen, die Liste mit variabler Größe durch DynamicList zu ersetzen, aber das Problem mit der dynamischen Liste, dass Sie nicht zum Element scrollen können, ist für einige Komponenten möglicherweise sehr nützlich, und eine solche Anforderung kann im Laufe der Zeit auftreten, sodass Sie nicht vorhersagen können, ob Reaktionsfenster passt zu Ihren Bedürfnissen.
Das zweite Problem, das ich sehe, ist die Leistung dynamischer Listen. Wenn Sie für dynamische Listen dieselbe Leistung wie für Listen mit variabler Größe bereitstellen können, ist es möglicherweise in Ordnung, sie zu löschen, auch wenn Sie scrollToItem nicht unterstützen. Andernfalls können Entwickler gesperrt werden In seltsamen Situationen, in denen die dynamische Liste langsam ist und keine Unterstützung für die Unterstützung von Elementen bietet, hat die Liste nur eine feste Elementhöhe.
Sie planen, die Liste mit variabler Größe durch DynamicList zu ersetzen, aber das Problem mit der dynamischen Liste, zu der Sie nicht zum Element scrollen können
Ich denke nicht, dass dies eine inhärente Einschränkung ist, sondern nur eine der aktuellen Implementierungen. Ich habe Ideen, wie ich diese Funktion anbieten könnte. Ob ich Zeit finde, mich damit zu befassen, ist eine andere Frage: Lächeln:
Das zweite Problem, das ich sehe, ist die Leistung dynamischer Listen. Wenn Sie für dynamische Listen dieselbe Leistung wie für Listen mit variabler Größe bereitstellen können, ist es möglicherweise in Ordnung, sie zu löschen, auch wenn Sie scrollToItem nicht unterstützen. Andernfalls können Entwickler gesperrt werden In seltsamen Situationen, in denen die dynamische Liste langsam ist und keine Unterstützung für die Unterstützung von Elementen bietet, hat die Liste nur eine feste Elementhöhe.
Schwer zu sagen, ob es auch funktioniert. Es scheint, als müsste die dynamische Liste mehr Arbeit leisten, sodass es wahrscheinlich ist, dass sie nicht ganz so gut funktioniert. Vielleicht ist der Unterschied signifikant, vielleicht auch nicht. Ich möchte in der Lage sein, einige Dinge zu unterstützen, die ich derzeit nicht habe, und ich denke, ich muss den Umfang reduzieren, um neue Funktionen hinzuzufügen. Wenn Sie derzeit mit der Variablenliste zufrieden sind, gibt es keinen Grund für ein Upgrade auf Version 2 (zumindest in Kürze).
@bvaughn Das sieht für mich nach Dokumentation aus!
Arbeiten Sie seit letztem Sommer daran? ;-);
Im Ernst - ich denke, Render Requisiten sind in diesem Zusammenhang sinnvoll, obwohl ich kein Fan bin.
Nein, ich habe heute Morgen geschrieben. Ich bin erschöpft.
Ich denke, Render Requisiten sind in diesem Zusammenhang sinnvoll, obwohl ich kein Fan bin.
Kannst du erklären, warum du kein Fan bist?
Könnte die Unterstützung horizontaler Listen / Raster als Opt-In-Funktion wie AutoSizer
(React-Virtualized-Auto-Sizer) sinnvoll sein?
Ich habe sowohl React-Virtualized als auch React-Window für horizontale Listen verwendet und finde die React-Window-API viel einfacher. Obwohl ich auf jeden Fall die Notwendigkeit der Ablehnung in der Hoffnung auf eine einfachere API verstehe.
Netzunterstützung ist noch geplant. Entscheiden Sie sich für horizontale Unterstützung, nein, nicht wirklich. Ich denke nicht, dass das Sinn machen würde.
@bvaughn Ich
Können Sie Mauerwerksgitter realisieren?
@nikitapilgrim Nein. Ich würde vorschlagen, nur die Masonry
-Komponente von react-virtualized
https://github.com/bvaughn/react-virtualized/blob/master/docs/Masonry.md
danke, aber seine arbeit nur mit reaktionsvirtualisiert?
@ Nikitapilgrim Yup . 👍
React-virtualized unterstützt eine Reihe von Funktionen, die React-Window nicht bietet.
Der Umfang des Reaktionsfensters wird drastisch reduziert, um das Paket kleiner und schneller zu machen . 😉
Wenn Sie Funktionen von React-Virtualized benötigen, empfehlen wir Ihnen, dabei zu bleiben - es ist immer noch eine großartige Bibliothek!
Ich bin auf react-window
gestoßen, weil ich nach einer Lösung für dieses react-virtualized
babel 7
Problem gesucht habe. Ich verwende die Komponenten react-virtualized
Masonry
, kann sie aber nach dem Upgrade von babel
nicht mehr verwenden.
Dies ist nicht der Ort, um Probleme mit React-Virtualized zu melden.
Einverstanden @bvaughn. Sie und @babangsund haben jedoch oben auf @nikitapilgrim geantwortet, dass eine Masonry
-Komponente nicht in react-window
und stattdessen react-virtualized
. Wenn sich ein Benutzer jedoch auf den neuesten [email protected]
und [email protected]
(z. B. bei create-react-app
), funktioniert react-virtualized
nicht unbedingt.
Ich denke, das sind nützliche Informationen für alle anderen, die das gleiche Kaninchenloch hinuntergehen.
¯ \ _ (ツ) _ / ¯
Hey, ich möchte eine dynamische Größenliste verwenden. Wo kann ich Version 2 herunterladen oder muss ich React Virtualise verwenden?
So sieht meine Liste mit einer Liste mit variabler Größe aus
Dies ist kein generisches Supportproblem. Bitte behalten Sie Kommentare zum Thema.
Feedback wird geschätzt
Ich verwende react-window
für ein Trello-ähnliches Produkt und hier einige Gedanken:
Requisiten rendern
Dies scheint aufgrund der Einfachheit und zur Vermeidung des genannten Nachteils eine gute Änderung zu sein. Außerdem ähnelt die API eher der FlatList von react-native. Ich erinnere mich, dass ich die Diskussion unter https://github.com/bvaughn/react-window/issues/85 gelesen habe
Weniger Komponenten
Keine horizontale Listenunterstützung mehr
Ich stimme sehr gegen die Entfernung von horizontal
Support und VariableSizeList
. Wie Sie sich vorstellen können, sind dies die beiden wichtigsten, die ich verwende. Ist ihre Implementierung wirklich zu belastend, um sie aufrechtzuerhalten? Wenn nicht, hoffe ich, dass Sie sie überdenken und behalten können.
Ich habe keine starken Meinungen zu den anderen Änderungen. Das Entfernen von overscanCount
macht mir ein wenig Sorgen, aber ich habe noch keine Anwendungsfälle erlebt, in denen noch ein benutzerdefinierter Wert erforderlich war, daher ist dies wahrscheinlich in Ordnung.
Hey @bvaughn! Danke für dieses Paket! Ich möchte Version 2 in mein Projekt bei der Arbeit integrieren. Haben Sie einen Baseballstadion, in dem dies veröffentlicht werden könnte?
Vielen Dank für diese Bibliothek und das Teilen Ihres Plans für die zukünftige Veröffentlichung. Es ist sehr hilfreich, uns dabei zu helfen, technische Schulden abzubauen.
Gibt es eine "einfache" Möglichkeit, WindowScroller
mit dem aktuellen react-window
und höher in Version 2 zu verhalten?
Wenn es nicht möglich ist, würde dies außerhalb des Umfangs dieser Version 2 liegen? oder könnte dies später hinzugefügt werden?
Mein Kontext ist, dass mein Layout eine Fußzeile enthält und die Verwendung eines modernen Ansatzes wie DynamicSizeList
eine zweite Bildlaufleiste einführen würde (eine für die Seite und eine für die Liste der Produkte).
Tolles Paket. Standardmäßig gespannt auf dynamische Höhenlisten - im Moment habe ich eine Reihe von benutzerdefinierten Logik geschrieben, um gerenderte Zeilenhöhen wieder an die übergeordnete Liste zu übergeben. Hoffentlich kann ich mit dieser neuen Version diese Logik entfernen. Vielen Dank für Ihre Arbeit!
@ltkn @mrdanimal
Es gibt bereits eine Möglichkeit, Windows Scroller zu verwenden:
https://github.com/bvaughn/react-window/issues/30#issuecomment -428868071
So geht's Unendlich in beide Richtungen scrollen, links oder rechts !!!
Wenn wir WindowScroller
ohne haben, hängt von react-virtualized
, das wird großartig. Weil das Ziel hinter react-window
es viel effizienter und weniger Code im Vergleich zu react-virtualized
, möchte ich also nicht WindowScroller
von react-virtualized
. Suchen Sie stattdessen nach einem separaten Paket wie react-virtualized-auto-sizer
.
Danke im Voraus.
@ Prabusamvel hm ..
Was ist der Vorteil eines separaten Pakets?
Ich habe mit der neuen DynamicSizeList herumgespielt. Sehr cool! Ich denke, eine große Verbesserung wäre, 'ttb' und 'btt' (von oben nach unten, von unten nach oben) in den Richtungstyp aufzunehmen. Derzeit gibt es keine saubere Möglichkeit, eine Liste zu implementieren, die nach oben scrollt, aber jede andere Richtung wird unterstützt.
@toddmacintyre Ich kann diese Version 2 nicht finden. Kann mich jemand führen?
@muhammedmagdi npm install react-window@next
Es wäre brillant, wenn Version 2 die von der Spezifikation hier geforderten DOM-Strukturen unterstützen könnte - https://www.w3.org/TR/wai-aria-1.1/#grid, da # 217 für uns immer noch ein Problem darstellt. Soweit ich Ihren Vorschlag für Version 2 im Moment beurteilen kann, ist dies nicht der Fall.
@mjurkowski @bvaughn yarn add react-window@next
installiert 1.6.0-alpha.1
. Auch beim Versuch, das Sandbox-Beispiel für dynamische Listen https://react-window-next.now.sh/#/examples/list/dynamic -size auszuführen, wird Error importing GitHub repository: Could not find package.json
ausgegeben
Wie wäre es, wenn Sie die index
in Grid übergeben - während Sie dabei sind? :)
Ein Teil unserer Anwendung erfordert ein Raster mit Spaltenüberschriften variabler Breite. Wir haben dies erreicht, indem wir eine horizontale Liste mit variabler Größe in Verbindung mit einem Raster verwendet und das Scrollen der beiden synchronisiert haben.
Durch das Entfernen horizontaler Listen wird verhindert, dass wir diese Benutzeroberfläche erstellen (oder wir müssen sie zumindest neu schreiben, um zwei Raster zu verwenden, bei denen das Spaltenüberschriftenraster eine einzelne Zeile enthält.
Das nächste Produkt sieht toll aus. Aber ich brauche sowohl horizontale als auch vertikale, also habe ich zu meiner Information meine eigene erstellt: https://www.npmjs.com/package/react-infinite-grid-scroller. Verwendet das Rasterlayout, React Hooks, IntersectionObserver und requestIdleCallback.
Feedback willkommen.
Ich habe das Gefühl, dass das Unterstützen von klebrigen Elementen eine großartige Ergänzung zum Reaktionsfenster wäre. Es ist ein ziemlich häufiger Anwendungsfall und lässt sich sowohl für Listen als auch für Grids einfach implementieren.
Die API könnte folgendermaßen aussehen:
<Grid
// First 2 columns are sticky
stickyLeft={2}
// Last column is not sticky (default value)
stickyRight={0}
// First and last rows are sticky
stickyTop={1}
stickyBottom={1}
/>
Die zwei Schlüsselelemente, damit die Klebrigkeit funktioniert, sind:
position: sticky
anstelle von absolute
und verwenden Sie margin-x
anstelle von left
und top
für die Achse, die nicht klebrig istDie Kosten für solch ein großartiges Feature scheinen vernünftig:
position: sticky
nicht unterstützen, sehen nur eine normale VersionWenn Sie der Meinung sind, dass dieser Anwendungsfall zu spezifisch ist, um so wie er ist unterstützt zu werden, besteht ein großer Kompromiss darin, nur Punkt 1 zu unterstützen. Wenn Sie angeben können, ob eine Zelle gerendert werden soll oder nicht, können Sie die Klebrigkeit leicht implementieren.
Bei Bedarf stehe ich gerne zur Verfügung.
unterstützt nicht das automatische Messen und Aktualisieren ihrer Größen.
Ich denke, das ist ein ziemlich großer Nachteil. Für fast jedes Raster, das ich geschrieben habe, benötige ich 3 oder 4 Spalten mit fester Breite (für eine Statusbezeichnung, einige Metadaten, einen Aufruf zum Handeln usw.) und 1 Spalte mit dynamischer Breite, die den Rest des verfügbaren Speicherplatzes einnimmt.
Ich schätze, dass "nicht unterstützt" nicht unbedingt bedeutet, dass dies mit dem Hinzufügen von zusätzlichem Code und Komponenten wie Autosizer nicht möglich ist. Es wäre einfach schön, wenn diese Anwendungsfälle gut überlegt und Lösungen für diejenigen dokumentiert würden, die eine benötigen dynamische Spalte, aber nicht für das gesamte Gepäck, das es mit sich bringt, reaktionsvirtualisiert werden wollen.
Es wäre einfach schön, wenn diese Anwendungsfälle gut überlegt und Lösungen für diejenigen dokumentiert würden, die eine dynamische Spalte benötigen
Völlig verstanden - aber praktisch gesehen würde das viel Mühe erfordern, und diese Bibliothek war eine Liebesarbeit (kein bezahltes Unterfangen). Leider hatte ich nicht einmal Zeit, meine Bemühungen um v2
Es wäre einfach schön, wenn diese Anwendungsfälle gut überlegt und Lösungen für diejenigen dokumentiert würden, die eine dynamische Spalte benötigen
Völlig verstanden - aber praktisch gesehen würde das viel Mühe erfordern, und diese Bibliothek war eine Liebesarbeit (kein bezahltes Unterfangen). Leider hatte ich nicht einmal Zeit, meine Bemühungen um v2 zu beenden, geschweige denn etwas aggressiveres. 😞
Jep. Ich verstehe das. Hoffentlich können solche Bemühungen von der Gemeinschaft geleitet werden.
Wäre schön - aber meiner Erfahrung nach passiert das nie: Lächeln:
Ich konnte WindowScroller
mit DynamicSizedList verwenden, wahrscheinlich aufgrund des Just-in-Time-Renderings, wodurch scrollTo nicht sehr gut funktioniert. Wird dies mit der neuen Version möglich sein?
Ich habe die Tatsache akzeptiert, dass ich weder Zeit noch Energie habe, um diese Bemühungen zu beenden. Wenn jemand in den von mir gestarteten Zweig eintreten und ihn beenden möchte, würde ich mich über Ihre Hilfe freuen. (Weitere Informationen zu List
und Grid
finden Sie in Ausgabe 6, um Just-in-Time-Messungen zu unterstützen.)
Hallo @bvaughn ,
Ich habe eine Diskussion auf meiner Gabel mit einigen zufälligen Notizen erstellt.
Lassen Sie mich wissen, ob etwas nicht auf der Liste stehen sollte oder nicht korrekt ist. Ich werde die Liste vervollständigen, wenn ich Fortschritte mache.
Sieht nach guten Sachen aus
Hilfreichster Kommentar
Horizontale Listen werden in unserem Fall häufig auf Mobilgeräten verwendet. Wir verwenden sie auch für die Steuerung mit unendlich scrollbaren Karussells. IMO muss etwas auf dem Handy haben.