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: 'xxxxxxxxx@hotmail.com',
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.
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.