Ich habe eine App mit ReactNative sowohl für iOS als auch für Android mit einem erstellt ListView
. Wenn Sie die Listenansicht mit einer gültigen Datenquelle füllen, wird am unteren Bildschirmrand die folgende Warnung angezeigt:
Warnung: Jedes Kind in einem Array oder Iterator sollte eine eindeutige "Schlüssel" -Stütze haben. Überprüfen Sie die Rendermethode von
ListView
.
Was ist der Zweck dieser Warnung? Nach der Nachricht verlinken sie auf diese Seite , auf der verschiedene Dinge besprochen werden, die nichts mit der Reaktion auf native, sondern mit webbasierten Reaktionen zu tun haben.
Meine ListView basiert auf folgenden Anweisungen:
render() {
var store = this.props.store;
return (
<ListView
dataSource={this.state.dataSource}
renderHeader={this.renderHeader.bind(this)}
renderRow={this.renderDetailItem.bind(this)}
renderSeparator={this.renderSeparator.bind(this)}
style={styles.listView}
/>
);
}
Meine DataSource besteht aus:
var detailItems = [];
detailItems.push( new DetailItem('plain', store.address) );
detailItems.push( new DetailItem('map', '') );
if(store.telefon) {
detailItems.push( new DetailItem('contact', store.telefon, 'Anrufen', 'fontawesome|phone') );
}
if(store.email) {
detailItems.push( new DetailItem('contact', store.email, 'Email', 'fontawesome|envelope') );
}
detailItems.push( new DetailItem('moreInfo', '') );
this.setState({
dataSource: this.state.dataSource.cloneWithRows(detailItems)
});
Und die ListView-Zeilen werden mit folgenden Dingen gerendert:
return (
<TouchableHighlight underlayColor='#dddddd'>
<View style={styles.infoRow}>
<Icon
name={item.icon}
size={30}
color='gray'
style={styles.contactIcon}
/>
<View style={{ flex: 1}}>
<Text style={styles.headline}>{item.headline}</Text>
<Text style={styles.details}>{item.text}</Text>
</View>
<View style={styles.separator}/>
</View>
</TouchableHighlight>
);
Alles funktioniert gut und wie erwartet, bis auf die Warnung, die mir als völliger Unsinn erscheint.
Das Hinzufügen einer Schlüsseleigenschaft zu meiner "DetailItem" -Klasse hat das Problem nicht gelöst.
Dies ist, was als Ergebnis von "cloneWithRows" wirklich an die ListView übergeben wird:
_dataBlob:
I/ReactNativeJS( 1293): { s1:
I/ReactNativeJS( 1293): [ { key: 2,
I/ReactNativeJS( 1293): type: 'plain',
I/ReactNativeJS( 1293): text: 'xxxxxxxxxx',
I/ReactNativeJS( 1293): headline: '',
I/ReactNativeJS( 1293): icon: '' },
I/ReactNativeJS( 1293): { key: 3, type: 'map', text: '', headline: '', icon: '' },
I/ReactNativeJS( 1293): { key: 4,
I/ReactNativeJS( 1293): type: 'contact',
I/ReactNativeJS( 1293): text: '(xxxx) yyyyyy',
I/ReactNativeJS( 1293): headline: 'Anrufen',
I/ReactNativeJS( 1293): icon: 'fontawesome|phone' },
I/ReactNativeJS( 1293): { key: 5,
I/ReactNativeJS( 1293): type: 'contact',
I/ReactNativeJS( 1293): text: '[email protected]',
I/ReactNativeJS( 1293): headline: 'Email',
I/ReactNativeJS( 1293): icon: 'fontawesome|envelope' },
I/ReactNativeJS( 1293): { key: 6, type: 'moreInfo', text: '', headline: '', icon: '' } ] },
Wie ein Schlüssel zeigt, hat jeder Datensatz eine Schlüsseleigenschaft. Die Warnung ist noch vorhanden.
quelle
DetailItem
benötigen Sie Schlüssel. Wenn sie bereits eindeutige Schlüssel haben, müssen Sie die anderen Rendermethoden (renderHeader, renderDetailItem, renderSeparator
) anzeigen . Sie funktionieren einwandfrei und werden erwartet, bis die Datenquelle in irgendeiner Weise geändert wird (z. B. werden Zeilen entfernt). Zu diesem Zeitpunkt weiß React nicht, was mit ihnen zu tun ist, wenn sie keine eindeutige Kennung haben.Antworten:
Ich habe jetzt schon eine Weile genau das gleiche Problem wie Sie und nachdem ich mir einige der obigen Vorschläge angesehen habe, habe ich das Problem endlich gelöst.
Es stellte sich heraus (zumindest für mich), dass ich der Komponente, die ich von meiner renderSeparator-Methode zurückgebe, einen Schlüssel (eine Requisite namens 'key') geben musste. Das Hinzufügen eines Schlüssels zu meiner renderRow oder renderSectionHeader hat nichts bewirkt, aber das Hinzufügen zu renderSeparator hat die Warnung gelöscht.
Hoffentlich hilft das.
quelle
SectionList
, müssen explizit eine Eigenschaft mit Namen Schlüsseln für jedenitem
RN glücklich zu machen.Sie müssen einen Schlüssel angeben .
Versuchen Sie dies in Ihren ListView-Zeilen, wenn Sie eine Schlüsseleigenschaft haben:
Wenn nicht, fügen Sie einfach das Element als Schlüssel hinzu:
quelle
Sie können auch die Iterationszahl (i) verwenden als
key
:quelle
Ändern Sie Ihren Code von:
Zu:
Dann gelöst.
quelle
Fügen Sie der Rendering-Stammkomponente der Liste einen Requisitenschlüssel hinzu.
quelle
Diese Warnung wird angezeigt, wenn Sie Ihren Listenelementen keinen Schlüssel hinzufügen.
quelle
Ich habe es behoben, indem ich der renderSeparator-Komponente eine Eigenschaft hinzugefügt habe. Der Code ist hier:
Die Schlüsselwörter dieser Warnung sind "eindeutig". SectionID + rowID geben einen eindeutigen Wert in ListView zurück.
quelle
Angenommen, die renderDetailItem-Methode hat die folgende Signatur ...
Versuchen Sie das ...
quelle
Der spezifische Code, mit dem ich das behoben habe, war:
Ich füge den spezifischen Code hinzu, da die Schlüssel eindeutig sein müssen - auch für Trennzeichen. Wenn Sie etwas Ähnliches tun, z. B. wenn Sie dies auf eine Konstante setzen, wird nur ein weiterer ärgerlicher Fehler bezüglich der Wiederverwendung von Schlüsseln angezeigt. Wenn Sie JSX nicht kennen, kann das Erstellen des Rückrufs an JS zum Ausführen der verschiedenen Teile ziemlich schmerzhaft sein.
Und in der ListView wird dies offensichtlich angehängt:
Dank an Coldbuffet und Nader Dabit, die mich auf diesen Weg geführt haben.
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
Hier basiert auf meinem Verständnis. Hoffentlich ist es hilfreich. Es soll eine Liste aller Komponenten als Beispiel dahinter rendern. Das Root-Tag jeder Komponente muss a haben
key
. Es muss nicht eindeutig sein. Es kann nicht seinkey=0
,key='0'
usw. Es sieht der Schlüssel nutzlos ist.quelle
Scheint, als ob beide Bedingungen erfüllt sind, vielleicht ist der Schlüssel ("Kontakt") das Problem
quelle
Dies kann nicht genug betont werden:
Schlüssel sind nur im Kontext des umgebenden Arrays sinnvoll .
"Wenn Sie beispielsweise eine ListItem-Komponente extrahieren, sollten Sie den Schlüssel für die <ListItem /> -Elemente im Array und nicht für das <li> -Element im ListItem selbst behalten." - https://reactjs.org/docs/lists-and-keys.html#extracting-components-with-keys
quelle
Die Sache, die mich auf dieses Problem aufmerksam gemacht hat, war, dass ich dachte, dass die Notwendigkeit eines Schlüssels für "echte" oder DOM-HTML-Elemente im Gegensatz zu den von mir definierten JSX-Elementen gilt.
Natürlich arbeiten wir mit React mit einem virtuellen DOM, daher sind die von uns definierten React JSX-Elemente
<MyElement>
genauso wichtig wie die Elemente, die wie echte DOM-HTML-Elemente aussehen<div>
.Ist das sinnvoll?
quelle
In meinem Fall habe ich die Ansicht "Karte" von Semantic UI React verwendet. Nachdem ich jeder von mir erstellten Karte einen Schlüssel hinzugefügt hatte, verschwand die Warnung, zum Beispiel:
quelle
Wenn Sie das
<Fade in>
Element für eine Reaktionsanwendung verwenden, fügenkey={}
Sie bitte auch ein Attribut hinzu, da sonst ein Fehler in der Konsole angezeigt wird.quelle