Keine Schlüsselkollision bei der Rückgabe identischer Arrays?

8

Ich habe kürzlich eine Antwort an eine Frage , als ich eine Beobachtung über key machte, als sie von einem Array zurückgegeben wurde.

Ich weiß bereits, dass Schlüssel unter Geschwisterkomponenten eindeutig sein müssen. Dies ist in der offiziellen React-Dokumentation angegeben, hier :

  

In Arrays verwendete Schlüssel sollten unter ihren Geschwistern eindeutig sein. Sie müssen jedoch nicht global eindeutig sein. Wir können die gleichen Schlüssel verwenden, wenn wir zwei verschiedene Arrays erstellen.

Im Gegensatz zu dem obigen fett gedruckten Text scheint es jedoch so zu sein, als ob React mit denselben Schlüsseln für identische Arrays funktioniert. Wie funktioniert das folgende Snippet und die Schlüssel kollidieren nicht?

%Vor% %Vor%

Offensichtlich funktioniert das nicht:

%Vor% %Vor%

Meine Frage ist also, warum funktioniert der erste Ausschnitt, aber nicht der zweite? Es scheint, dass sie beide genau das gleiche Ergebnis liefern sollten?

    
Chris 22.06.2017, 09:22
quelle

3 Antworten

7

Antwort legt fest, wie die createHierarchyRenderer Methode / Funktion funktioniert. Quelle createHierarchyRenderer.js

Es ist reducingRight und das Anfügen von Komponenten durch Rendern an den Conspect, der das Ergebnis enthält.

Erzeugt renderHierarchy , was 2d Array von Komponenten ist, also ... Ihre renderArray Aufrufe haben unterschiedliche Indizes in der Hierarchie, die ihre Hierarchien voneinander unabhängig machen.

Der zweite Fall funktioniert nicht, da Schlüssel Pseudohierarchie sind, um die Leistung zu steigern - Sie können dies tun, ohne zu keying, aber - es ist sehr schlechte Praxis für größere render queue. Übergeben Sie also key - überschreibt die durch key dargestellte Dimension.

Bonus:

Warum funktioniert es, ohne Schlüssel zu übergeben? Welche Schlüssel sind die Besten? Wie verbessern?!

Quelle :

%Vor%

Diese Methode wird von der Methode traverseStackChildrenImpl in derselben Datei aufgerufen. Wenn Sie sich in diese Magie vertiefen:

%Vor%

Sie werden verstehen, warum es funktioniert, und Sie werden wissen, warum das Keying ohne Tasten funktioniert, und wo Sie Leistungseinbußen erleiden. Es ist schön, key zu übergeben, aber ... React kann automatisch den Index für uns übergeben, key ist dafür ausgelegt, das id des Komponentenerstellerobjekts zu übernehmen ... Zum Beispiel:

%Vor%

Es macht keinen Unterschied, dass key nicht übergeben wird, aber es wird als schlechte Praxis betrachtet:

%Vor%

key magic wurde entwickelt, um die ID des Benutzers dazu zu bringen, den Rest der Benutzer nicht neu zu rendern, wenn das Array innerhalb von fe angehängt wird. %Code%. Das beste verfügbare Setup ist:

%Vor%     
Daniel Mizerski 22.06.2017, 09:37
quelle
4

Nachdem ich die wertvollen Inputs aus den anderen hier geposteten Antworten betrachtet hatte, grub ich ein wenig tiefer und erstellte die beiden Snippets in meiner eigenen Anwendung neu und inspizierte dann die Komponente mit dem React Developer Tool.

Ich habe Folgendes gefunden:

Erstes Snippet:

Im ersten Ausschnitt, in dem die Funktion renderArray() verwendet wird, enthält children der übergeordneten <div> nicht 9 <p> -Tags als untergeordnete Elemente, sondern 3 Arrays, die jeweils enthalten 3 <p> -Tags.

Das ist zunächst nicht so offensichtlich, weil die gerenderte Ausgabe in den Dev-Tools (linker Teil) 9 Kinder und nicht 3 bedeutet.

Hier habe ich den ersten, vierten und siebten Punkt erweitert. Das sind die Punkte, die ich key als 0 angegeben habe.

Zweites Snippet:

Im zweiten Ausschnitt, in dem alle <p> -Tags direkt als untergeordnete Elemente des <div> platziert werden, erhalten wir eine ähnliche Ausgabe (wenn wir die Elemente 4-9 wegen Schlüsselkollision nicht anzeigen), aber die dev-tools zeige an, dass die <div> die erwarteten 9 Kinder hat. Daher die Kollision.

Wie beim vorherigen Snippet habe ich den ersten und vierten Punkt erweitert, wobei key für 0 steht. (vergaß die siebte).

DL; DR

Wenn eine React-Komponente ein Array als children erhält, wird der Inhalt dieses Arrays nicht entpackt / zerstört und als untergeordnete Elemente ausgegeben. Stattdessen bleibt das Array als children und dient als transparenter Container für seinen Inhalt.

Daher gibt es keine Schlüsselkollision wegen:

  • Das Elternteil <div> hat 3 Felder als unmittelbare children - nicht die 9 <p> -Komponenten.
  • Jede <p> -Komponente ist in ihrem übergeordneten Array "gesperrt", weil sie dort definiert ist. Es kann sich offensichtlich nicht plötzlich in eines der anderen Arrays bewegen.
  • Jede <p> -Komponente hat% key in ihrem Eltern-Array (0-2); der einzige Ort Kollisionen wären möglich.
Chris 22.06.2017 11:14
quelle
1

Reaction-Schlüssel müssen für jedes Element innerhalb einer Instanz eines übergeordneten Elements eindeutig sein. In Ihrem Fall haben Sie 3 Instanzen von {this.renderArray()} , jede mit einer eigenen inneren ID. So haben Kinder innerhalb jeder Instanz eindeutige Schlüssel, aber sie sind keine Geschwister mit Kindern aus anderen Instanzen.

Siehe dieses Beispiel aus der offiziellen Dokumentation: Ссылка

    
Andrei Duca 22.06.2017 09:39
quelle

Tags und Links