Creé una aplicación con ReactNative tanto para iOS como para Android con una extensiónListView
. Al llenar la vista de lista con una fuente de datos válida, se imprime la siguiente advertencia en la parte inferior de la pantalla:
Advertencia: Cada niño en una matriz o iterador debe tener una propiedad de "clave" única. Compruebe el método de renderizado de
ListView
.
¿Cuál es el propósito de esta advertencia? Después del mensaje, enlazan a esta página , donde se discuten cosas diferentes que no tienen nada que ver con react native, sino con reactjs basados en web.
Mi ListView está construido con esas declaraciones:
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}
/>
);
}
Mi fuente de datos consta de algo como:
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)
});
Y las ListView-Rows se representan con cosas como:
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>
);
Todo funciona bien y como se esperaba, excepto la advertencia que me parece una completa tontería.
Agregar una propiedad clave a mi clase "DetailItem" no resolvió el problema.
Esto es, lo que realmente se pasará a ListView como resultado de "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: 'xxxxxxxxx@hotmail.com',
I/ReactNativeJS( 1293): headline: 'Email',
I/ReactNativeJS( 1293): icon: 'fontawesome|envelope' },
I/ReactNativeJS( 1293): { key: 6, type: 'moreInfo', text: '', headline: '', icon: '' } ] },
Como ve una clave, cada registro tiene una propiedad clave. La advertencia aún existe.
DetailItem
es que sus s necesiten tener claves. Si ya tienen claves únicas, necesita mostrar los otros métodos de renderizado (renderHeader, renderDetailItem, renderSeparator
). Funcionan bien y se esperan hasta que la fuente de datos se modifique de alguna manera (las filas se eliminan, por ejemplo), momento en el que React no sabrá qué hacer con ellos cuando no tengan un identificador único.