React: Listenelemente mit eindeutigem "Schlüssel" werden neu gerendert, wenn sich die Reihenfolge der Elemente ändert.

Erstellt am 15. Juli 2018  ·  3Kommentare  ·  Quelle: facebook/react

Möchten Sie eine Funktion anfordern oder einen Fehler melden?
Insekt

Wie ist das aktuelle Verhalten?
Wenn sich beim Rendern einer Liste von Elementen mit key als eindeutige Eigenschaft für jedes Elementelement die Reihenfolge der Elemente gegenüber dem vorherigen Rendern ändert, werden die Elementelemente, deren Indizes geändert wurden, neu gerendert (eine neue Instanz wird erstellt) statt neu gerendert -Verwendung vorhandener Instanz (über Schlüssel abgebildet).

Für zB https://codesandbox.io/s/r5p48kzop
Rendern einer Liste boxes mit jeder Box mit id , top , left & color Requisiten. Alle 750ms aktualisieren wir die ( top , left ) Werte für alle Elemente im boxes Array.

Wenn sich beim Aktualisieren die Reihenfolge der Elemente nicht ändert, wird jede Box an ihre neue Position animiert. Wenn wir jedoch die Zeile 31 auskommentieren, die die Kästchen mischt, werden nur Elemente, die ihre Position vom vorherigen Rendern beibehalten, an neue Positionen animiert.

Sie können dieses Verhalten in der Sandbox beobachten. Mit _shuffle springen manchmal Boxen an ihre neue Position, während sie mit _shuffle aus immer animieren.

Wenn das aktuelle Verhalten ein Fehler ist, stellen Sie bitte die Schritte zur Reproduktion und wenn möglich eine minimale Demo des Problems bereit. Fügen Sie den Link zu Ihrem JSFiddle (https://jsfiddle.net/Luktwrdm/) oder CodeSandbox (https://codesandbox.io/s/new) Beispiel unten ein:
https://codesandbox.io/s/r5p48kzop

Was ist das erwartete Verhalten?
Unabhängig von der Reihenfolge von boxes alle Boxelemente an ihre neuen Positionen animiert werden, da für sie eine einzigartige key Eigenschaft festgelegt ist.

Welche React-Versionen und welche Browser/Betriebssysteme sind von diesem Problem betroffen?
Reagieren Sie 16.3.2 & 16.4.1 , Chrome, MacOS.

Hilfreichster Kommentar

Hey @dhruvparmar372!

Dies scheint eine Einschränkung des DOM zu sein. Um dies zu demonstrieren, habe ich dieses JSFiddle erstellt, das die Reihenfolge von zwei DOM-Knoten ändert und dann eine Klasse anwendet, um einen Übergang auszulösen.

Es stellt sich heraus, dass Sie dieses Problem umgehen können, indem Sie einen

Ich habe Ihrer CodeSandbox ein wenig Code hinzugefügt, um es sichtbar zu machen, wenn eine Komponente von React neu erstellt wird, indem Sie <Box /> in eine Klassenkomponente ändern und eine eindeutige ID im Konstruktor erstellen. Wie Sie sehen, bleibt die ID konsistent: https://codesandbox.io/s/jn42wvl343

Darüber hinaus habe ich den Reflow-Workaround auf Ihr Beispiel angewendet, indem ich das Update in zwei setState s aufgeteilt habe. Der erste ändert die Reihenfolge, dann lösen wir einen Reflow aus und ändern anschließend die Position. Dies scheint in Chrome, Firefox, Safari und Edge gut zu funktionieren (CodeSandbox unterstützt IE11 nicht, daher konnte ich diesen Browser nicht testen).

Alle 3 Kommentare

Hey @dhruvparmar372!

Dies scheint eine Einschränkung des DOM zu sein. Um dies zu demonstrieren, habe ich dieses JSFiddle erstellt, das die Reihenfolge von zwei DOM-Knoten ändert und dann eine Klasse anwendet, um einen Übergang auszulösen.

Es stellt sich heraus, dass Sie dieses Problem umgehen können, indem Sie einen

Ich habe Ihrer CodeSandbox ein wenig Code hinzugefügt, um es sichtbar zu machen, wenn eine Komponente von React neu erstellt wird, indem Sie <Box /> in eine Klassenkomponente ändern und eine eindeutige ID im Konstruktor erstellen. Wie Sie sehen, bleibt die ID konsistent: https://codesandbox.io/s/jn42wvl343

Darüber hinaus habe ich den Reflow-Workaround auf Ihr Beispiel angewendet, indem ich das Update in zwei setState s aufgeteilt habe. Der erste ändert die Reihenfolge, dann lösen wir einen Reflow aus und ändern anschließend die Position. Dies scheint in Chrome, Firefox, Safari und Edge gut zu funktionieren (CodeSandbox unterstützt IE11 nicht, daher konnte ich diesen Browser nicht testen).

hey @philipp-spiess danke für die Klärung des Problems und die Beispiele für den Workaround.

Hallo @philipp-spiess

Ich habe das gleiche Problem mit der Sortierliste 😔
Leider funktioniert Ihr Codesandbox-Beispiel oben nicht mehr (

Hier ist ein Beispiel:
https://jsfiddle.net/9odLvbrx/
Es sortiert Elemente beim Klicken mit einem einfachen CSS-Übergang.
Das Problem besteht darin, dass der Übergang nur für das ausgewählte Element angezeigt wird und der Rest weggelassen wird.

Ich weiß, wie man das Problem umgeht (im Code kommentiert), aber es funktioniert nur bei Listen, deren Artikelmenge sich nie ändert. Wenn ich also Elemente hinzufügen oder entfernen möchte, wird die Sache unglaublich komplex. Wie kann ich Ihre Reflow-Überladungslösung verwenden, um dies in meinem Beispiel zu verwirklichen?

Danke im Voraus! 😊

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen