Construí um aplicativo com ReactNative para iOS e Android com um ListView
. Ao preencher o listview com uma fonte de dados válida, o seguinte aviso é impresso na parte inferior da tela:
Aviso: cada filho em uma matriz ou iterador deve ter uma prop "chave" exclusiva. Verifique o método de renderização de
ListView
.
Qual é o propósito deste aviso? Após a mensagem, eles são direcionados para esta página , onde são discutidas coisas completamente diferentes que não têm nada a ver com a reação nativa, mas com reações baseadas na web.
My ListView é construído com essas instruções:
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}
/>
);
}
Minha fonte de dados consiste em 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)
});
E as ListView-Rows são renderizadas com coisas 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>
);
Tudo funciona bem e conforme o esperado, exceto o aviso que parece ser um disparate completo para mim.
Adicionar uma propriedade-chave à minha classe "DetailItem" não resolveu o problema.
Isto é, o que realmente será passado para o 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: '[email protected]',
I/ReactNativeJS( 1293): headline: 'Email',
I/ReactNativeJS( 1293): icon: 'fontawesome|envelope' },
I/ReactNativeJS( 1293): { key: 6, type: 'moreInfo', text: '', headline: '', icon: '' } ] },
Como uma chave vê, cada registro possui uma propriedade chave. O aviso ainda existe.
fonte
DetailItem
precisa de chaves. Se eles já têm chaves exclusivas, você precisa mostrar os outros métodos de renderização (renderHeader, renderDetailItem, renderSeparator
). Eles estão funcionando bem e são esperados até que a fonte de dados seja modificada de alguma forma (as linhas são removidas, por exemplo), momento em que o React não saberá o que fazer com eles se não tiverem um identificador exclusivo.Respostas:
Eu tenho exatamente o mesmo problema que você há algum tempo e, depois de examinar algumas das sugestões acima, finalmente resolvi o problema.
Acontece que (pelo menos para mim de qualquer maneira), eu precisava fornecer uma chave (um prop chamado 'chave') para o componente que estou retornando do meu método renderSeparator. Adicionar uma chave a meu renderRow ou renderSectionHeader não fez nada, mas adicioná-la a renderSeparator fez o aviso desaparecer.
Espero que ajude.
fonte
SectionList
, tem que adicionar explicitamente uma propriedade com a chave do nome para cada umitem
para deixar RN feliz.Você precisa fornecer uma chave .
Tente fazer isso em suas ListView Rows se você tiver uma propriedade-chave:
Caso contrário, tente apenas adicionar o item como a chave:
fonte
Você também pode usar a contagem de iteração (i) como
key
:fonte
Altere seu código de:
Para:
Então resolvido.
fonte
Adicione uma 'chave' prop ao componente raiz de renderização da lista.
fonte
Este aviso surge quando você não adiciona uma chave aos itens da lista. De acordo com o react js Docs -
fonte
Eu corrigi ao adicionar uma propriedade ao componente renderSeparator, o código está aqui:
As palavras-chave desse aviso são "exclusivo", sectionID + rowID retornam um valor exclusivo em ListView.
fonte
Supondo que o método renderDetailItem tenha a seguinte assinatura ...
Tente fazer isso ...
fonte
O código específico que usei para corrigir isso foi:
Estou incluindo o código específico porque você precisa que as chaves sejam exclusivas - mesmo para separadores. Se você fizer algo semelhante, por exemplo, se definir isso como uma constante, receberá apenas outro erro irritante sobre a reutilização de chaves. Se você não conhece JSX, construir um retorno de chamada para JS para executar as várias partes pode ser uma dor de cabeça.
E no ListView, obviamente anexando isto:
Crédito para coldbuffet e Nader Dabit que me indicou este caminho.
fonte
Verifique: key = undef !!!
Você também recebeu a mensagem de aviso:
se o seu código estiver completo, mas se estiver
someValue is undefined !!! Verifique isso primeiro. Você pode economizar horas.
fonte
Aqui está baseado no meu entendimento. Espero que seja útil. Ele deve renderizar uma lista de todos os componentes como exemplo. A tag raiz de cada componente precisa ter um
key
. Não precisa ser único. Não pode serkey=0
,key='0'
etc. Parece que a chave é inútil.fonte
Parece que ambas as condições foram atendidas, talvez a chave ('contato') seja o problema
fonte
Isso não pode ser enfatizado o suficiente:
As chaves só fazem sentido no contexto da matriz circundante .
"Por exemplo, se você extrair um componente ListItem, deverá manter a chave nos elementos <ListItem /> na matriz em vez de no elemento <li> no próprio ListItem." - https://reactjs.org/docs/lists-and-keys.html#extracting-components-with-keys
fonte
O que me fez tropeçar nesse problema foi que eu pensei que a necessidade de uma chave se aplicava ao que parece ser "real" ou elementos HTML DOM, em oposição aos elementos JSX que eu defini.
É claro que com o React estamos trabalhando com um DOM virtual, portanto, os elementos React JSX que definimos
<MyElement>
são tão importantes para ele quanto os elementos que se parecem com os elementos HTML DOM reais<div>
.Isso faz sentido?
fonte
No meu caso, eu estava usando a visualização "Cartão" do Semantic UI React. Depois de adicionar uma chave a cada cartão que construí, o aviso desapareceu, por exemplo:
fonte
Se você estiver usando o
<Fade in>
elemento para um aplicativo de reação, adicione okey={}
atributo nele também ou você verá um erro no console.fonte