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.
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! 😊
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/jn42wvl343Darü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).