Código básico do FlatList lança Aviso - Reagir nativo

129

O FlatList não parece estar funcionando. Eu recebo este aviso.

VirtualizedList: faltando chaves para itens, especifique uma propriedade de chave em cada item ou forneça um keyExtractor personalizado.

Código:

<FlatList 
  data={[{name: 'a'}, {name: 'b'}]} 
  renderItem={
    (item) => <Text key={Math.random().toString()}>{item.name}</Text>
  } 
  key={Math.random().toString()} />
Edison D'souza
fonte
3
@ Li357 ... e persistente se os dados não forem alterados. Chaves aleatórias causarão a renderização novamente de cada item em cada alteração de dados, o que seria muito ineficiente.
Jules
como descrito abaixo, deve ser uma seqüência de caracteres, há uma discusão no repositório oficial aqui . Acho que a equipe nativa do react queria salvar os usuários para não usarem o índice como uma chave, mas não é uma boa solução. Eu deveria poder usar o db id como uma chave. não preciso convertê-lo em uma string.
peja

Respostas:

313

Simplesmente faça o seguinte:

<FlatList 
  data={[{name: 'a'}, {name: 'b'}]} 
  renderItem={
    ({item}) => <Text>{item.name}</Text>
  } 
  keyExtractor={(item, index) => index.toString()}
/>

Fonte: aqui

Raio
fonte
{item.name} não funcionou. Mas {item.item.name} funcionou para mim. Pode ser porque eu dei (item) em vez de ({item}) em renderItem. Obrigado @Raymond
Edison D'souza
1
Por causa dos suspensórios. Se você usar chaves, precisará adicionar uma declaração de retorno.
Ray
7
Isso pode não funcionar. Após excluir e adicionar alguns elementos, ele começou a exibir itens duplicados. Eu acho que o objetivo do keyExtractor é exclusivamente um item. Idealmente, você deve ter um ID exclusivo para cada item e usar o ID como chave. por exemplo, keyExtractor = {item => item.id}
JustWonder 19/01
2
@ JustWonder - à direita; se sua lista tiver itens removidos, você não poderá usar o índice como chave e precisará encontrar outra maneira de gerar uma chave exclusiva para cada item. Para o caso em que apenas coisas são adicionadas, essa abordagem é adequada.
Jules
19
o índice retornado deve ser uma string:keyExtractor={(item, index) => index.toString()}
roadev
41

Você não precisa usar keyExtractor. Os documentos React Native são um pouco obscuros, mas a keypropriedade deve estar em cada elemento da datamatriz, e não no componente filho renderizado. Então, ao invés de

<FlatList
  data={[{id: 'a'}, {id: 'b'}]}
  renderItem={({item}) => <View key={item.id} />}
/>
// React will give you a warning about there being no key prop

que é o que você esperaria, basta colocar um keycampo em cada elemento da datamatriz:

<FlatList
  data={[{key: 'a'}, {key: 'b'}]}
  renderItem={({item}) => <View />}
/>
// React is happy!

E definitivamente não coloque uma string aleatória como chave.

Ben
fonte
13

Isso funcionou para mim:

<FlatList
  data={[{name: 'a'}, {name: 'b'}]} 
  keyExtractor={(item, index) => index.toString()}
/>
rjh
fonte
1
oukeyExtractor={ ( item, index ) => `${index}` }
Ivor Scott
9

Você pode usar

 <FlatList   
  data={[]}  
  keyExtractor={(item, index) => index.toString()} 
 />

NOTA: Usando index.toString () ou seja, espera-se que seja string.

Ramusesan
fonte
5

Tenha um 'id' nos seus dados

const data = [
{
  name: 'a',
  id: 1
},
{
  name: 'b',
  id: 2
}];

<FlatList 
  data={data}
  renderItem={
    (item) => <Text>{item.name}</Text>
  } 
  keyExtractor={item => item.id}
/>

Espero que isto ajude !!!

Yogaraj Saravanan
fonte
2

Uma solução simples é fornecer a cada entrada uma chave exclusiva antes da renderização FlatList, pois é isso que o subjacente VirtualizedListprecisa acompanhar cada entrada.

 users.forEach((user, i) => {
    user.key = i + 1;
 });

O aviso aconselha fazer isso primeiro ou fornece um extrator de chave personalizado.

Torta 'Oh' Pah
fonte
2

este código funciona para mim:

const content = [
  {
    name: 'Marta',
    content: 'Payday in November: Rp. 987.654.321',
  },]
 
  <FlatList
      data= {content}
      renderItem = { ({ item }) => (
        <View style={{ flexDirection: 'column',             justifyContent: 'center' }}>
      <Text style={{ fontSize: 20, fontWeight: '300', color: '#000000' }}>{item.name}</Text>
      <Text style={{ color: '#000000' }}>{item.content}</Text>
        
        />
      )}
      keyExtractor={(item,index) => item.content}
    />

harisman nug
fonte
2

Isso não deu nenhum aviso (transformando o índice em uma string):

<FlatList 
  data={[{name: 'a'}, {name: 'b'}]} 
  keyExtractor={(item, index) => index+"" }
  renderItem={
    (item) => <Text>{item.name}</Text>
  } 
/>
JulienRioux
fonte
1

caso seus dados não sejam um objeto: [na verdade, eles estão usando cada índice de item (na matriz) como uma chave]

   data: ['name1','name2'] //declared in constructor
     <FlatList
  data= {this.state.data}
  renderItem={({item}) => <Text>{item}</Text>}
  ItemSeparatorComponent={this.renderSeparator}
keyExtractor={(item, index) => index.toString()}
/>
Mahgol Fa
fonte
0

Tentei a resposta de Ray, mas recebi um aviso de que "a chave deve ser uma string". A seguinte versão modificada funciona bem para suprimir o aviso original e esta chave de cadeia, se você não tiver uma boa chave exclusiva no próprio item:

keyExtractor={(item, index) => item + index}

Obviamente, se você possui uma chave única óbvia e boa no item em si, basta usá-la.

CodeBrew
fonte
0

Certifique-se de escrever a declaração de retorno, caso contrário ele não retornará nada ... Aconteceu comigo.

Hamza Ahmed Jameel
fonte
-2

Isso funcionou para mim:

<FlatList
  data={items}
  renderItem={({ title }) => <Text>{title}</Text> }}
  keyExtractor={() => Math.random().toString(36).substr(2, 9)} />

Transformando o keyExtractorem um stringmas, em vez de usar o índice, use um número gerado aleatoriamente.

Quando eu usei keyExtractor={(item, index) => index.toString()}, nunca funcionou e ainda deu um aviso. Mas talvez isso funcione para alguém?

Coelho branco
fonte
2
Supõe-se que as chaves sejam únicas. Usar uma sequência aleatória não é uma boa ideia. Como mencionado acima, causará nova renderização não necessária, pois a função aleatória retornará um valor diferente se o reagir tentar renderizar novamente devido a qualquer outra alteração.
Edison D'souza
Eu ouvi você cara obrigado por isso. Mas como mais poderá obter uma string única, o que se tem como 5flatlists
Coelho Branco