Grundlegender FlatList-Code löst Warning - React Native aus

129

FlatList scheint nicht zu funktionieren. Ich bekomme diese Warnung.

VirtualizedList: Fehlende Schlüssel für Elemente. Geben Sie für jedes Element eine Schlüsseleigenschaft an oder geben Sie einen benutzerdefinierten keyExtractor an.

Code:

<FlatList 
  data={[{name: 'a'}, {name: 'b'}]} 
  renderItem={
    (item) => <Text key={Math.random().toString()}>{item.name}</Text>
  } 
  key={Math.random().toString()} />
Edison D'souza
quelle
3
@ Li357 ... und persistent, wenn die Daten unverändert bleiben. Zufällige Schlüssel führen dazu, dass jedes Element bei jeder Datenänderung erneut gerendert wird, was sehr ineffizient wäre.
Jules
wie unten beschrieben , sollte ein String sein, gibt es eine disccusion auf offiziellen Repo hier . Ich denke, das reaktionsnative Team wollte Benutzer speichern, um den Index nicht als Schlüssel zu verwenden, aber es ist keine gute Lösung. Ich sollte in der Lage sein, die Datenbank-ID als Schlüssel zu verwenden. Ich muss es nicht in einen String konvertieren.
Peja

Antworten:

313

Mach das einfach:

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

Quelle: hier

Strahl
quelle
{item.name} hat nicht funktioniert. Aber {item.item.name} hat bei mir funktioniert. Kann daran liegen, dass ich in renderItem (item) anstelle von ({item}) angegeben habe. Vielen Dank @Raymond
Edison D'souza
1
Wegen der geschweiften Klammern. Wenn Sie geschweifte Klammern verwenden möchten, müssen Sie eine return-Anweisung hinzufügen.
Ray
7
Dies funktioniert möglicherweise nicht. Nach dem Löschen und Hinzufügen einiger Elemente wurden doppelte Elemente angezeigt. Ich denke, der Zweck von keyExtractor ist es, einen Artikel eindeutig zu machen. Idealerweise sollten Sie für jedes Element eine eindeutige ID haben und die ID als Schlüssel verwenden. zB keyExtractor = {item => item.id}
JustWonder
2
@ JustWonder - richtig; Wenn in Ihrer Liste Elemente entfernt werden sollen, können Sie den Index nicht als Schlüssel verwenden, und Sie müssen einen anderen Weg finden, um für jedes Element einen eindeutigen Schlüssel zu generieren. Für den Fall, dass nur Dinge hinzugefügt werden, ist dieser Ansatz in Ordnung.
Jules
19
Der zurückgegebene Index muss eine Zeichenfolge sein:keyExtractor={(item, index) => index.toString()}
Roadev
41

Sie müssen nicht verwenden keyExtractor. Die React Native-Dokumente sind etwas unklar, aber die keyEigenschaft sollte in jedem Element des dataArrays und nicht in der gerenderten untergeordneten Komponente enthalten sein. Also eher als

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

Was Sie erwarten würden, müssen Sie nur ein keyFeld in jedes Element des dataArrays einfügen:

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

Und auf keinen Fall eine zufällige Zeichenfolge als Schlüssel verwenden.

Ben
quelle
13

Das hat bei mir funktioniert:

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

Sie können verwenden

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

HINWEIS: Verwenden von index.toString (), dh als Zeichenfolge erwartet.

Ramusesan
quelle
5

Haben Sie eine 'ID' in Ihren Daten

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

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

Hoffe das hilft !!!

Yogaraj Saravanan
quelle
2

Eine einfache Lösung besteht darin, jedem Eintrag vor dem Rendern einen eindeutigen Schlüssel zu geben FlatList, da der Basiswert dies VirtualizedListbenötigt, um jeden Eintrag zu verfolgen.

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

In der Warnung wird empfohlen, dies zuerst zu tun oder einen benutzerdefinierten Schlüsselextraktor bereitzustellen.

Pie 'Oh' Pah
quelle
2

Dieser Code funktioniert für mich:

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
quelle
2

Dies gab keine Warnung (Umwandlung des Index in eine Zeichenfolge):

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

Falls Ihre Daten kein Objekt sind: [Tatsächlich wird jeder Elementindex (im Array) als Schlüssel verwendet]

   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
quelle
0

Versuchte Rays Antwort, bekam dann aber eine Warnung, dass "der Schlüssel eine Zeichenfolge sein muss". Die folgende modifizierte Version funktioniert gut, um das Original und diese Zeichenfolgenschlüsselwarnung zu unterdrücken, wenn Sie keinen guten eindeutigen Schlüssel für das Element selbst haben:

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

Wenn Sie einen offensichtlichen und guten eindeutigen Schlüssel für den Artikel selbst haben, können Sie diesen natürlich einfach verwenden.

CodeBrew
quelle
0

Stellen Sie sicher, dass Sie eine return-Anweisung schreiben, da sonst nichts zurückgegeben wird.

Hamza Ahmed Jameel
quelle
-2

Das hat bei mir funktioniert:

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

Verwandeln Sie das keyExtractorin ein, stringaber anstatt Index zu verwenden, verwenden Sie eine zufällig generierte Zahl.

Als ich es benutzte keyExtractor={(item, index) => index.toString()}, hat es nie funktioniert und trotzdem eine Warnung ausgegeben. Aber vielleicht funktioniert das für jemanden?

weißer Hase
quelle
2
Schlüssel sollen eindeutig sein. Die Verwendung einer zufälligen Zeichenfolge ist keine gute Idee. Wie oben erwähnt, führt dies zu einem nicht erforderlichen erneuten Rendern, da die Zufallsfunktion einen anderen Wert zurückgibt, wenn reag aufgrund einer anderen Änderung versucht, erneut zu rendern.
Edison D'souza
Ich höre dich, Kumpel, danke dafür. Aber wie sonst würden Sie eine einzigartige Saite bekommen, was wäre, wenn Sie 5flatlists
White Rabbit