I built an app with ReactNative both for iOS and android with a ListView
. When populating the listview with a valid datasource, the following warning is printed at the bottom of the screen:
Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of
ListView
.
What is the purpose of this warning? After the message they link to this page, where complete different things are discussed which have nothing to do with react native, but with web based reactjs.
My ListView is built with those statements:
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}
/>
);
}
My DataSource consists of something like:
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)
});
And the ListView-Rows are rendered with stuff like:
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>
);
Everything works fine and as expected, except the warning which seems to be complete nonsense to me.
Adding a key-property to my "DetailItem"-Class didn't solve the issue.
This is, what really will be passed to the ListView as a result of "cloneWithRows":
_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: '' } ] },
As one key see, each record has a key property. The warning still exists.
DetailItem
s need to have keys. If they already have unique keys, you need show the other render methods (renderHeader, renderDetailItem, renderSeparator
). They are working fine and expected until the data source is modified in someway (rows are removed, for example) at which point React won't know what to do with them when they don't have an unique identifier. – Pastypat