Le code FlatList de base lève un avertissement - React Native


129

FlatList ne semble pas fonctionner. Je reçois cet avertissement.

VirtualizedList: clés manquantes pour les éléments, assurez-vous de spécifier une propriété de clé sur chaque élément ou fournissez un keyExtractor personnalisé.

Code:

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

3
@ Li357 ... et persistant si les données restent inchangées. Les clés aléatoires entraîneront un nouveau rendu de chaque élément à chaque changement de données, ce qui serait très inefficace.
Jules

comme décrit ci-dessous, il devrait s'agir d'une chaîne, il y a une discussion sur le repo officiel ici . Je pense que l'équipe de react-native voulait empêcher les utilisateurs d'utiliser l'index comme clé, mais ce n'est pas une bonne solution. Je devrais pouvoir utiliser db id comme clé. je n'ai pas à le convertir en chaîne.
peja

Réponses:


313

Faites simplement ceci:

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

Source: ici


{item.name} n'a pas fonctionné. Mais {item.item.name} a fonctionné pour moi. Peut-être parce que j'ai donné (item) au lieu de ({item}) dans renderItem. Merci @Raymond
Edison D'souza

1
À cause des accolades. Si vous allez utiliser des accolades, vous devez ajouter une instruction return.
Ray

7
Cela peut ne pas fonctionner. Après avoir supprimé et ajouté certains éléments, il a commencé à afficher les éléments dupliqués. Je pense que le but de keyExtractor est uniquement un élément. Idéalement, vous devriez avoir un identifiant unique pour chaque élément et utiliser l'identifiant comme clé. eg keyExtractor = {item => item.id}
JustWonder

2
@JustWonder - à droite; si votre liste doit avoir des éléments supprimés, vous ne pouvez pas utiliser l'index comme clé et vous devez trouver un autre moyen de générer une clé unique pour chaque élément. Pour le cas où des éléments ne sont ajoutés que jamais, cette approche convient.
Jules

19
l'index retourné doit être une chaîne:keyExtractor={(item, index) => index.toString()}
roadev

41

Vous n'avez pas besoin d'utiliser keyExtractor. Les documents React Native sont un peu flous mais la keypropriété doit aller dans chaque élément du datatableau plutôt que dans le composant enfant rendu. Donc plutôt que

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

ce à quoi vous vous attendez, il vous suffit de mettre un keychamp dans chaque élément du datatableau:

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

Et ne mettez certainement pas une chaîne aléatoire comme clé.


13

Cela a fonctionné pour moi:

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

1
oukeyExtractor={ ( item, index ) => `${index}` }
Ivor Scott

9

Vous pouvez utiliser

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

REMARQUE: en utilisant index.toString (), c'est-à-dire qu'il devrait être une chaîne.


5

Avoir un 'identifiant' dans vos données

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

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

J'espère que cela t'aides !!!


2

Une solution simple consiste simplement à donner à chaque entrée une clé unique avant le rendu avec FlatList, car c'est ce dont le sous-jacent a VirtualizedListbesoin pour suivre chaque entrée.

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

L'avertissement conseille de faire cela en premier ou fournit un extracteur de clé personnalisé.


2

ce code fonctionne pour moi:

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}
    />


2

Cela n'a donné aucun avertissement (transformation de l'index en chaîne):

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

1

au cas où vos données ne seraient pas un objet: [en fait, il utilise chaque index d'élément (dans le tableau) comme clé]

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

0

J'ai essayé la réponse de Ray, mais j'ai reçu un avertissement indiquant que "la clé doit être une chaîne". La version modifiée suivante fonctionne bien pour supprimer l'original et cet avertissement de clé de chaîne si vous n'avez pas une bonne clé unique sur l'élément lui-même:

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

Bien sûr, si vous avez une clé unique évidente et bonne sur l'élément lui-même, vous pouvez simplement l'utiliser.



-2

Cela a fonctionné pour moi:

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

Transformer le keyExtractoren un stringmais au lieu d'utiliser un index, utilisez un nombre généré de manière aléatoire.

Quand je l'ai utilisé keyExtractor={(item, index) => index.toString()}, cela n'a jamais fonctionné et a quand même émis un avertissement. Mais peut-être que cela fonctionne pour quelqu'un?


2
Les clés sont censées être uniques. Utiliser une chaîne aléatoire n'est pas une bonne idée. Comme mentionné ci-dessus, cela entraînera un re-rendu non requis car la fonction aléatoire renvoie une valeur différente si react tente de refaire le rendu en raison de tout autre changement.
Edison D'souza

Je vous entends mec merci pour ça. Mais comment obtiendriez-vous une chaîne unique, et si vous aviez comme 5flatlists
White Rabbit
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.