Podstawowy kod FlatList generuje ostrzeżenie - React Native

129

Wygląda na to, że FlatList nie działa. Otrzymuję to ostrzeżenie.

VirtualizedList: brak kluczy dla elementów, upewnij się, że określono właściwość klucza dla każdego elementu lub podaj niestandardowy keyExtractor.

Kod:

<FlatList 
  data={[{name: 'a'}, {name: 'b'}]} 
  renderItem={
    (item) => <Text key={Math.random().toString()}>{item.name}</Text>
  } 
  key={Math.random().toString()} />
Edison D'souza
źródło
3
@ Li357 ... i trwałe, jeśli dane są niezmienione. Losowe klucze spowodują ponowne renderowanie każdego elementu przy każdej zmianie danych, co byłoby bardzo nieefektywne.
Jules
jak opisano poniżej powinna być ciągiem, jest disccusion na oficjalnego repo tutaj . Myślę, że zespół react-native chciał oszczędzić użytkownikom, aby nie używali indeksu jako klucza, ale nie jest to dobre rozwiązanie. Powinienem być w stanie użyć identyfikatora db jako klucza. nie muszę go konwertować na ciąg.
peja

Odpowiedzi:

313

Po prostu zrób to:

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

Źródło: tutaj

Promień
źródło
{item.name} nie działa. Ale {item.item.name} zadziałał dla mnie. Może dlatego, że podałem (item) zamiast ({item}) w renderItem. Dzięki @Raymond
Edison D'souza
1
Z powodu kręconych szelek. Jeśli zamierzasz używać nawiasów klamrowych, musisz dodać instrukcję return.
Ray
7
To może się nie udać. Po usunięciu i dodaniu niektórych elementów zaczął wyświetlać zduplikowane elementy. Myślę, że celem keyExtractor jest unikatowa pozycja. Idealnie byłoby, gdybyś miał unikalny identyfikator dla każdego przedmiotu i używał go jako klucza. np. keyExtractor = {item => item.id}
JustWonder
2
@JustWonder - racja; jeśli z listy zostaną usunięte pozycje, nie możesz użyć indeksu jako klucza i musisz znaleźć inny sposób generowania unikalnego klucza dla każdego elementu. W przypadku, gdy rzeczy są tylko dodawane, takie podejście jest w porządku.
Jules
19
zwracany indeks musi być ciągiem znaków:keyExtractor={(item, index) => index.toString()}
roadev
41

Nie musisz używać keyExtractor. Dokumentacja React Native jest trochę niejasna, ale keywłaściwość powinna znajdować się w każdym elemencie datatablicy, a nie w renderowanym komponencie potomnym. Więc raczej niż

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

czego można się spodziewać, wystarczy umieścić keypole w każdym elemencie datatablicy:

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

I zdecydowanie nie umieszczaj losowego ciągu jako klucza.

Ben
źródło
13

To zadziałało dla mnie:

<FlatList
  data={[{name: 'a'}, {name: 'b'}]} 
  keyExtractor={(item, index) => index.toString()}
/>
rjh
źródło
1
lubkeyExtractor={ ( item, index ) => `${index}` }
Ivor Scott
9

Możesz użyć

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

UWAGA: Za pomocą index.toString () oczekuje się, że będzie to łańcuch.

Ramusan
źródło
5

Miej „identyfikator” w swoich danych

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

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

Mam nadzieję że to pomoże !!!

Yogaraj Saravanan
źródło
2

Prostym rozwiązaniem jest po prostu nadanie każdemu wpisowi unikatowego klucza przed renderowaniem za pomocą FlatList, ponieważ tego VirtualizedListpotrzebuje element bazowy, aby śledzić każdy wpis.

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

Ostrzeżenie sugeruje zrobienie tego w pierwszej kolejności lub zapewnia niestandardowy ekstraktor kluczy.

Ciasto „Oh” Pah
źródło
2

ten kod działa dla mnie:

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
źródło
2

To nie dało żadnego ostrzeżenia (przekształcenie indeksu w łańcuch):

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

w przypadku, gdy Twoje dane nie są przedmiotem: [w rzeczywistości używa indeksu każdego elementu (w tablicy) jako klucza]

   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
źródło
0

Wypróbowałem odpowiedź Raya, ale otrzymałem ostrzeżenie, że „klucz musi być łańcuchem”. Następująca zmodyfikowana wersja działa dobrze, aby ukryć oryginał i to ostrzeżenie o kluczu ciągu, jeśli nie masz dobrego unikalnego klucza na samym elemencie:

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

Oczywiście, jeśli masz oczywisty i dobry unikalny klucz do samego przedmiotu, możesz go po prostu użyć.

CodeBrew
źródło
0

Upewnij się, że napiszesz instrukcję powrotu, w przeciwnym razie nic nie zwróci .. Stało się ze mną.

Hamza Ahmed Jameel
źródło
-2

To zadziałało dla mnie:

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

Zamieniając keyExtractorw a, stringale zamiast używać indeksu, użyj losowo wygenerowanej liczby.

Kiedy użyłem keyExtractor={(item, index) => index.toString()}, to nigdy nie działało i nadal wyrzucałem ostrzeżenie. Ale może to działa na kogoś?

biały Królik
źródło
2
Klucze mają być unikalne, a używanie losowego ciągu nie jest dobrym pomysłem. Jak wspomniano powyżej, spowoduje to niepotrzebne ponowne renderowanie, ponieważ funkcja random zwraca inną wartość, jeśli reaguje na próbę ponownego renderowania z powodu jakiejkolwiek innej zmiany.
Edison D'souza
Słyszę, dzięki za to stary. Ale jak inaczej można uzyskać unikalny ciąg, co jeśli masz 5flatlists
White Rabbit