Основний код FlatList кидає попередження - React Native


129

Здається, FlatList не працює. Я отримую це попередження.

VirtualizedList: відсутні ключі для елементів, обов’язково вкажіть властивість ключа для кожного елемента або вкажіть спеціальний ключExtractor.

Код:

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

3
@ Li357 ... і зберігається, якщо дані не змінюються. Випадкові клавіші призведуть до повторного відображення кожного елемента при кожній зміні даних, що було б дуже неефективно.
Жуль

як описано нижче , він повинен бути рядком, є disccusion на офіційному репо тут . Я думаю, що рідна команда react хотіла врятувати користувачів, щоб не використовувати індекс як ключовий, але це не гарне рішення. Я повинен мати можливість використовувати ідентифікатор db як ключ. мені не доведеться перетворювати його в рядок.
peja

Відповіді:


313

Просто зробіть це:

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

Джерело: тут


{item.name} не працює. Але {item.item.name} працював на мене. Можливо тому, що я дав (item) замість ({item}) у renderItem. Дякуємо @Raymond
Edison D'souza

1
Через фігурні брекети. Якщо ви збираєтесь використовувати фігурні дужки, вам потрібно додати заяву про повернення.
Рей

7
Це може не спрацювати. Після видалення та додавання деяких елементів він почав відображати дублювані елементи. Я думаю, що мета keyExtractor - унікальний предмет. В ідеалі ви повинні мати унікальний ідентифікатор для кожного елемента та використовувати його як ключ. наприклад, keyExtractor = {item => item.id}
JustWonder

2
@JustWonder - правильно; якщо у вашому списку будуть видалені елементи, ви не можете використовувати індекс як ключ, і ви повинні знайти інший спосіб створення унікального ключа для кожного елемента. У випадку, коли речі тільки коли-небудь додаються, такий підхід чудово.
Жуль

19
повернутий індекс повинен бути рядком:keyExtractor={(item, index) => index.toString()}
roadev

41

Не потрібно використовувати keyExtractor. Документи React Native дещо незрозумілі, але keyвластивість повинна міститись у кожному елементі dataмасиву, а не у складеному дочірньому компоненті. Тож, ніж

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

що ви очікуєте, вам просто потрібно ввести keyполе в кожен елемент dataмасиву:

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

І точно не кладіть випадкову рядок як ключ.


13

Це працювало для мене:

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

1
абоkeyExtractor={ ( item, index ) => `${index}` }
Івор Скотт

9

Можна використовувати

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

ПРИМІТКА: Використовуючи index.toString (), тобто очікуваний рядок.


5

Майте "id" у своїх даних

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

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

Сподіваюся, це допомагає !!!


2

Просте рішення - просто дати кожному запису унікальний ключ перед рендерінгом FlatList, оскільки саме для цього VirtualizedListслід відстежувати кожен запис.

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

Попередження виконує поради, які роблять це спочатку, або надає спеціальний інструмент витяжки ключів


2

цей код працює для мене:

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

Це не дало жодного попередження (перетворення індексу в рядок):

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

1

у випадку, якщо ваші Дані не є об’єктом: [насправді він використовує кожен індекс елемента (у масиві) як ключ]

   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

Спробував Рей, але потім отримав попередження, що "ключ повинен бути рядок". Наступна модифікована версія добре працює для придушення оригіналу та попередження цього рядкового ключа, якщо у вас немає хорошого унікального ключа на самому елементі:

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

Звичайно, якщо у вас є очевидний і хороший унікальний ключ на самому предметі, ви можете просто ним скористатися.



-2

Це працювало для мене:

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

Перетворення keyExtractorв, stringале замість індексу використовуйте випадкове генероване число.

Коли я використовував keyExtractor={(item, index) => index.toString()}, це ніколи не спрацьовувало і все одно виводило попередження. Але, можливо, це працює для когось?


2
Ключі повинні бути унікальними. Використання випадкових рядків не є хорошою ідеєю. Як було сказано вище, це спричинить необов’язкове повторне відображення, оскільки випадкова функція повертає інше значення, якщо реакція намагається повторно відобразити через будь-які інші зміни.
Едісон Д'уза

Я чую, чувак, дякую за це. Але як інакше ви отримаєте унікальну струну, що робити, якщо вам подобається 5flatlists
Білий Кролик
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.