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

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


{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.


13

To zadziałało dla mnie:

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

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.


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 !!!


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.


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


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

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

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ć.



-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ś?


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.