Ich erstelle eine React-Komponente, die eine JSON-Datenquelle akzeptiert und eine sortierbare Tabelle erstellt.
Jeder der dynamischen Datenzeilen ist ein eindeutiger Schlüssel zugewiesen, aber ich erhalte immer noch die Fehlermeldung:
Jedes Kind in einem Array sollte eine eindeutige "Schlüssel" -Stütze haben.
Überprüfen Sie die Rendermethode von TableComponent.
Meine TableComponent
Rendermethode gibt Folgendes zurück:
<table>
<thead key="thead">
<TableHeader columns={columnNames}/>
</thead>
<tbody key="tbody">
{ rows }
</tbody>
</table>
Das TableHeader
Komponente ist eine einzelne Zeile und hat auch einen eindeutigen Schlüssel.
Jedes row
In rows
wird aus einer Komponente mit einem eindeutigen Schlüssel erstellt:
<TableRowItem key={item.id} data={item} columns={columnNames}/>
Und das TableRowItem
sieht so aus:
var TableRowItem = React.createClass({
render: function() {
var td = function() {
return this.props.columns.map(function(c) {
return <td key={this.props.data[c]}>{this.props.data[c]}</td>;
}, this);
}.bind(this);
return (
<tr>{ td(this.props.item) }</tr>
)
}
});
Was verursacht den eindeutigen Schlüssel-Prop-Fehler?
javascript
reactjs
Brett DeWoody
quelle
quelle
key
Eigenschaft haben. Es wird ReactJS helfen, Verweise auf die entsprechenden DOM-Knoten zu finden und nur den Inhalt innerhalb des Markups zu aktualisieren, aber nicht die gesamte Tabelle / Zeile neu zu rendern.rows
Array oder vorzugsweise eine jsfiddle teilen? Sie brauchen keine Notwendigkeitkey
Eigenschaft aufthead
undtbody
durch die Art und Weise.Antworten:
Sie sollten jedem untergeordneten Element sowie jedem Element in untergeordneten Elementen einen Schlüssel hinzufügen .
Auf diese Weise kann React die minimale DOM-Änderung verarbeiten.
In Ihrem Code versucht jeder
<TableRowItem key={item.id} data={item} columns={columnNames}/>
, einige Kinder ohne Schlüssel in ihnen zu rendern.Überprüfen Sie dieses Beispiel .
Versuchen Sie, das
key={i}
aus dem<b></b>
Element in den Divs zu entfernen (und überprüfen Sie die Konsole).Wenn wir im Beispiel dem
<b>
Element keinen Schlüssel geben und nur den aktualisieren möchtenobject.city
, muss React die gesamte Zeile gegenüber nur dem Element neu rendern.Hier ist der Code:
Die Antwort von @Chris unten geht viel detaillierter als diese Antwort. Bitte werfen Sie einen Blick auf https://stackoverflow.com/a/43892905/2325522
Reagieren Sie auf die Dokumentation zur Bedeutung von Schlüsseln bei der Abstimmung: Schlüssel
quelle
key
Wert für die Requisite für jedes Element eindeutig ist, und platzieren Sie diekey
Requisite an der Komponente, die den Arraygrenzen am nächsten liegt. In React Native habe ich beispielsweise zuerst versucht,key
Requisiten in<Text>
Komponenten zu integrieren. Allerdings musste ich es auf eine<View>
Komponente setzen, die übergeordnet ist<Text>
. Wenn Array == [(Ansicht> Text), (Ansicht> Text)], müssen Sie es in Ansicht setzen. Kein Text.Seien Sie vorsichtig, wenn Sie über Arrays iterieren !!
Es ist ein weit verbreitetes Missverständnis, dass die Verwendung des Index des Elements im Array eine akzeptable Methode ist, um den Fehler zu unterdrücken, mit dem Sie wahrscheinlich vertraut sind:
In vielen Fällen ist dies jedoch nicht der Fall! Dies ist ein Anti-Muster , das in einigen Situationen zu unerwünschtem Verhalten führen kann .
Die
key
Requisite verstehenReact verwendet die
key
Requisite, um die Beziehung zwischen Komponente und DOM-Element zu verstehen, die dann für den Abstimmungsprozess verwendet wird . Es ist daher sehr wichtig, dass der Schlüssel immer eindeutig bleibt , da sonst die Wahrscheinlichkeit groß ist, dass React die Elemente verwechselt und das falsche mutiert. Es ist auch wichtig, dass diese Schlüssel bei allen erneuten Rendern statisch bleiben , um die beste Leistung zu erzielen.Davon abgesehen muss man das oben Gesagte nicht immer anwenden, vorausgesetzt, es ist bekannt, dass das Array vollständig statisch ist. Die Anwendung von Best Practices wird jedoch nach Möglichkeit empfohlen.
Ein React-Entwickler sagte in dieser GitHub-Ausgabe :
Kurz gesagt, a
key
sollte sein:Mit der
key
StützeStudieren Sie gemäß der obigen Erläuterung die folgenden Beispiele sorgfältig und versuchen Sie, den empfohlenen Ansatz nach Möglichkeit umzusetzen.
Schlecht (möglicherweise)
Dies ist wohl der häufigste Fehler, der beim Durchlaufen eines Arrays in React auftritt. Dieser Ansatz ist technisch nicht "falsch" , sondern nur ... "gefährlich", wenn Sie nicht wissen, was Sie tun. Wenn Sie ein statisches Array durchlaufen, ist dies ein absolut gültiger Ansatz (z. B. ein Array von Links in Ihrem Navigationsmenü). Wenn Sie jedoch Elemente hinzufügen, entfernen, neu anordnen oder filtern, müssen Sie vorsichtig sein. Schauen Sie sich diese ausführliche Erklärung in der offiziellen Dokumentation an.
Code-Snippet anzeigen
In diesem Snippet verwenden wir ein nicht statisches Array und beschränken uns nicht darauf, es als Stapel zu verwenden. Dies ist ein unsicherer Ansatz (Sie werden sehen warum). Beachten Sie, dass beim Hinzufügen von Elementen am Anfang des Arrays (im Grunde genommen die Verschiebung) der Wert für jedes Element erhalten
<input>
bleibt. Warum? Weil daskey
nicht jedes Element eindeutig identifiziert.Mit anderen Worten, zunächst
Item 1
hatkey={0}
. Wenn wir das zweite Element hinzufügen, wird das oberste ElementItem 2
gefolgt vonItem 1
dem zweiten Element. Doch jetztItem 1
hatkey={1}
und nichtkey={0}
mehr. Stattdessen hatItem 2
jetztkey={0}
!!Aus diesem
<input>
Grund glaubt React, dass sich die Elemente nicht geändert haben, da derItem
With-Schlüssel0
immer oben steht!Warum ist dieser Ansatz nur manchmal schlecht?
Dieser Ansatz ist nur dann riskant, wenn das Array irgendwie gefiltert, neu angeordnet oder Elemente hinzugefügt / entfernt werden. Wenn es immer statisch ist, ist es absolut sicher zu bedienen. Zum Beispiel kann ein Navigationsmenü wie
["Home", "Products", "Contact us"]
mit dieser Methode sicher durchlaufen werden, da Sie wahrscheinlich nie neue Links hinzufügen oder neu anordnen werden.Kurz gesagt, hier ist, wann Sie den Index sicher verwenden können als
key
:Hätten wir stattdessen in dem Snippet oben, schoben das zusätzliche Element am Ende des Arrays, die Reihenfolge für jedes vorhandenes Element würde immer richtig sein.
Sehr schlecht
Während dieser Ansatz wahrscheinlich die Eindeutigkeit der Schlüssel garantiert, erzwingt er immer eine Reaktion, um jedes Element in der Liste neu zu rendern, selbst wenn dies nicht erforderlich ist. Dies ist eine sehr schlechte Lösung, da sie die Leistung stark beeinträchtigt. Ganz zu schweigen davon, dass man die Möglichkeit einer Schlüsselkollision nicht ausschließen kann, wenn
Math.random()
dieselbe Zahl zweimal erzeugt wird.Sehr gut
Dies ist wohl der beste Ansatz, da eine Eigenschaft verwendet wird, die für jedes Element im Dataset eindeutig ist. Wenn beispielsweise
rows
Daten enthalten sind, die aus einer Datenbank abgerufen wurden, kann der Primärschlüssel der Tabelle verwendet werden ( normalerweise eine automatisch inkrementierende Zahl ).Gut
Dies ist auch ein guter Ansatz. Wenn Ihr Datensatz keine Daten enthält, die die Eindeutigkeit garantieren ( z. B. ein Array beliebiger Zahlen ), besteht die Möglichkeit einer Schlüsselkollision. In solchen Fällen ist es am besten, manuell eine eindeutige Kennung für jedes Element im Dataset zu generieren, bevor Sie darüber iterieren. Vorzugsweise beim Mounten der Komponente oder beim Empfangen des Datasets ( z. B. von
props
oder von einem asynchronen API-Aufruf ), um dies nur einmal und nicht jedes Mal zu tun , wenn die Komponente erneut gerendert wird. Es gibt bereits eine Handvoll Bibliotheken, die Ihnen solche Schlüssel zur Verfügung stellen können. Hier ist ein Beispiel: React-Key-Index .quelle
toString()
, um in Zeichenfolgen zu konvertieren, anstatt sie als Nummer zu belassen. Ist es wichtig, sich daran zu erinnern?key
. Ich bin mir nicht sicher, warum sie es konvertieren.key
sowieso immer ein String ist.Dies kann jemandem helfen oder nicht, aber es kann eine Kurzreferenz sein. Dies ähnelt auch allen oben dargestellten Antworten.
Ich habe viele Standorte, die eine Liste mit der folgenden Struktur erstellen:
Nach ein wenig Versuch und Irrtum (und einigen Frustrationen) wurde es durch Hinzufügen einer Schlüsseleigenschaft zum äußersten Block behoben. Beachten Sie auch, dass das <> -Tag jetzt durch das Tag ersetzt wird.
Natürlich habe ich den iterierenden Index (Index) naiv verwendet, um den Schlüsselwert im obigen Beispiel zu füllen. Idealerweise verwenden Sie etwas, das für das Listenelement eindeutig ist.
quelle
Warnung: Jedes Kind in einem Array oder Iterator sollte eine eindeutige "Schlüssel" -Stütze haben.
Dies ist eine Warnung, da für Array-Elemente, über die wir iterieren werden, eine eindeutige Ähnlichkeit erforderlich ist.
React behandelt das iterierende Rendern von Komponenten als Arrays.
Eine bessere Möglichkeit, dies zu beheben, besteht darin, einen Index für die Array-Elemente bereitzustellen, über die Sie iterieren möchten. Beispiel:
Index ist React eingebaute Requisiten.
quelle
Fügen Sie einfach den eindeutigen Schlüssel zu Ihren Komponenten hinzu
quelle
Check: key = undef !!!
Sie haben auch die Warnmeldung erhalten:
Wenn Ihr Code vollständig ist, aber wenn aktiviert
someValue ist undefiniert !!! Bitte überprüfen Sie dies zuerst. Sie können Stunden sparen.
quelle
Beste Lösung, um einen eindeutigen Schlüssel für die Reaktion zu definieren: Innerhalb der Karte haben Sie den Namen post initialisiert und dann den Schlüssel durch key = {post.id} definiert. In meinem Code sehen Sie, dass ich das Namenselement definiere und dann den Schlüssel durch key = {item.id definiere }:
quelle
Dies ist eine Warnung, aber wenn Sie dies ansprechen, werden die Reaktionen viel schneller , .
Dies liegt daran
React
, dass jedes Element in der Liste eindeutig identifiziert werden muss. Nehmen wir an, ob sich der Status eines Elements dieser Liste in Reacts ändertVirtual DOM
muss React herausfinden, welches Element geändert wurde und wo im DOM es geändert werden muss, damit das Browser-DOM mit dem virtuellen Reacts-DOM synchronisiert wird.Als Lösung fügen Sie einfach
key
jedemli
Tag ein Attribut hinzu . Dieskey
sollte für jedes Element ein eindeutiger Wert sein.quelle
key
Requisite hinzufügen . Wenn Sie keine angeben, weist React automatisch eine zu (den aktuellen Index der Iteration).key={i}
. Es hängt also von den Daten ab, die Ihr Array enthält. Wenn Sie zum Beispiel die Liste haben["Volvo", "Tesla"]
, wird der Volvo offensichtlich durch den Schlüssel und den Tesla mit identifiziert - denn dies ist die Reihenfolge, in der sie in der Schleife erscheinen. Wenn Sie nun das Array neu anordnen, werden die Schlüssel ausgetauscht. Da "Objekt" immer noch oben steht, wird diese Änderung für React eher als "Umbenennen" als als Neuordnung interpretiert. Die richtigen Tasten hier müßten , um sein, dann . Sie ordnen nicht immer zur Laufzeit neu, aber wenn Sie dies tun, ist dies ein Risiko.0
1
0
1
0
Dies wird das Problem lösen.
quelle
Ich habe diese Fehlermeldung erhalten, weil
<></>
sie für einige Elemente im Array zurückgegeben wurde, wenn sie stattdessen zurückgegeben werdennull
muss.quelle
Ich habe dies mit Guid für jeden Schlüssel wie folgt behoben: Guid generieren:
Und dann diesen Wert den Markern zuweisen:
quelle
Grundsätzlich sollten Sie den Index des Arrays nicht als eindeutigen Schlüssel verwenden. Stattdessen können Sie a verwenden
setTimeout(() => Date.now(),0)
, um den eindeutigen Schlüssel oder die nicht liquide UUID oder eine andere Methode festzulegen , mit der eine eindeutige ID generiert wird, jedoch nicht der Index des Arrays als eindeutige ID.quelle