Código básico FlatList arroja Advertencia - React Native

129

FlatList no parece estar funcionando. Recibo esta advertencia.

VirtualizedList: faltan claves para los elementos, asegúrese de especificar una propiedad clave en cada elemento o proporcione un keyExtractor personalizado.

Código:

<FlatList 
  data={[{name: 'a'}, {name: 'b'}]} 
  renderItem={
    (item) => <Text key={Math.random().toString()}>{item.name}</Text>
  } 
  key={Math.random().toString()} />
Edison D'souza
fuente
3
@ Li357 ... y persistente si los datos no cambian. Las claves aleatorias provocarán la devolución de cada elemento en cada cambio de datos, lo que sería muy ineficiente.
Jules
como se describe a continuación, debe ser una cadena, hay una discusión sobre el repositorio oficial aquí . Creo que el equipo react-native quería salvar a los usuarios para que no usaran el índice como clave, pero no es una buena solución. Debería poder usar db id como clave. No tengo que convertirlo en una cadena.
peja

Respuestas:

313

Simplemente haz esto:

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

Fuente: aquí

Rayo
fuente
{item.name} no funcionó. Pero {item.item.name} funcionó para mí. Puede ser porque le di (item) en lugar de ({item}) en renderItem. Gracias @Raymond
Edison D'souza
1
Debido a las llaves. Si va a usar llaves, debe agregar una declaración de devolución.
Ray
77
Esto puede no funcionar. Después de eliminar y agregar algunos elementos, comenzó a mostrar elementos duplicados. Creo que el propósito de keyExtractor es únicamente un elemento. Idealmente, debe tener una identificación única para cada elemento y usar la identificación como clave. ej. keyExtractor = {item => item.id}
JustWonder
2
@JustWonder - derecha; Si su lista va a tener elementos eliminados, no puede usar el índice como clave, y debe encontrar otra forma de generar una clave única para cada elemento. Para el caso en el que solo se agregan cosas, este enfoque está bien.
Jules
19
el índice devuelto debe ser una cadena:keyExtractor={(item, index) => index.toString()}
roadev
41

No necesitas usar keyExtractor. Los documentos React Native no están claros, pero la keypropiedad debe ir en cada elemento de la datamatriz en lugar de en el componente secundario representado. Entonces en lugar de

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

que es lo que esperarías, solo necesitas poner un keycampo en cada elemento de la datamatriz:

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

Y definitivamente no pongas una cadena aleatoria como clave.

Ben
fuente
13

Esto funcionó para mí:

<FlatList
  data={[{name: 'a'}, {name: 'b'}]} 
  keyExtractor={(item, index) => index.toString()}
/>
rjh
fuente
1
okeyExtractor={ ( item, index ) => `${index}` }
Ivor Scott, el
9

Puedes usar

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

NOTA: Usar index.toString (), es decir, se espera que sea una cadena.

Ramusesan
fuente
5

Tener una 'identificación' en sus datos

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

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

Espero que esto ayude !!!

Yogaraj Saravanan
fuente
2

Una solución simple es dar a cada entrada una clave única antes de renderizar FlatList, ya que eso es lo que el subyacente VirtualizedListnecesita para rastrear cada entrada.

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

La advertencia aconseja primero hacer esto, o proporcionar un extractor de claves personalizado.

Pie 'Oh' Pah
fuente
2

este código me funciona:

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

nug harisman
fuente
2

Esto no dio ninguna advertencia (transformando el índice en una cadena):

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

en caso de que sus datos no sean un objeto: [de hecho, está utilizando cada índice de elemento (en la matriz) como clave]

   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
fuente
0

Intenté la respuesta de Ray, pero luego recibí una advertencia de que "la clave debe ser una cadena". La siguiente versión modificada funciona bien para suprimir el original y esta advertencia de clave de cadena si no tiene una buena clave única en el elemento en sí:

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

Por supuesto, si tiene una clave única obvia y buena en el elemento en sí, puede usarla.

CodeBrew
fuente
0

Asegúrese de escribir la declaración de devolución, de lo contrario no devolverá nada ... Sucedió conmigo.

Hamza Ahmed Jameel
fuente
-2

Esto funcionó para mí:

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

Convirtiendo el keyExtractoren un stringpero en lugar de usar el índice, use un número generado al azar.

Cuando lo usé keyExtractor={(item, index) => index.toString()}, nunca funcionó y todavía echó una advertencia. Pero tal vez esto funciona para alguien?

conejo blanco
fuente
2
Se supone que las claves son únicas. Usar una secuencia aleatoria no es una buena idea. Como se mencionó anteriormente, causará una nueva representación no requerida ya que la función aleatoria devuelve un valor diferente si react intenta volver a representar debido a cualquier otro cambio.
Edison D'souza
Te escucho amigo gracias por eso. Pero, ¿de qué otra forma obtendrías una cadena única? ¿Qué pasaría si tuvieras como 5flatlists
White Rabbit?