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.