Базовый код FlatList выдает предупреждение - React Native


129

FlatList, похоже, не работает. Я получаю это предупреждение.

VirtualizedList: отсутствуют ключи для элементов, обязательно укажите свойство ключа для каждого элемента или предоставьте настраиваемый keyExtractor.

Код:

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

3
@ Li357 ... и постоянный, если данные не изменились. Случайные ключи будут вызывать повторную визуализацию каждого элемента при каждом изменении данных, что было бы очень неэффективно.
Жюль

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

Ответы:


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
Эдисон Д'суза

1
Из-за фигурных скобок. Если вы собираетесь использовать фигурные скобки, вам нужно добавить оператор возврата.
Ray

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

В ваших данных должен быть идентификатор

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
Ключи должны быть уникальными. Использование случайной строки - не лучшая идея. Как упоминалось выше, это вызовет необязательный повторный рендеринг, поскольку функция random возвращает другое значение, если response пытается повторно выполнить рендеринг из-за любого другого изменения.
Эдисон Д'суза 05

Я слышал, чувак, спасибо за это. Но как еще вы получите уникальную строку, что, если бы у вас было 5flatlists
White Rabbit
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.