FlatList: qué es, API y optimización en React Native

Autor: IT Sectr Publicado: 2026-07-05 Tiempo de lectura: 10 min

FlatList es el componente principal de React Native para mostrar listas de alto rendimiento con virtualización de elementos. A diferencia de ScrollView, FlatList renderiza solo los elementos visibles de la pantalla, ahorrando memoria y CPU. El componente admite desplazamiento horizontal y vertical, pull-to-refresh y carga infinita. Obtenga más información sobre la arquitectura de listas en la documentación de Meta.

Puntos clave

  • FlatList es un componente de lista virtualizado que renderiza solo los elementos visibles y los reutiliza durante el desplazamiento
  • El rendimiento se logra mediante renderizado por ventanas: los elementos fuera de la pantalla no se crean
  • La API incluye renderItem, keyExtractor, ItemSeparatorComponent, ListHeaderComponent y ListFooterComponent
  • Las listas horizontales se configuran mediante el indicador horizontal y cambian la dirección de desplazamiento al eje X
  • La optimización requiere una configuración adecuada de keyExtractor, useMemo para datos y getItemLayout para tamaños fijos

¿Qué es FlatList?

FlatList es un componente de React Native que implementa una lista virtualizada con renderizado de alto rendimiento para grandes volúmenes de datos. El componente está construido sobre VirtualizedList y proporciona una API declarativa para crear listas planas de cualquier complejidad.

FlatList se introdujo en React Native 0.43 como reemplazo del obsoleto ListView. Según Meta (2026), FlatList se utiliza en el 85% de las aplicaciones de React Native que trabajan con listas. El componente admite todos los escenarios comunes: contactos, fuentes de noticias, catálogos de productos y chats.

Historia y lugar en el ecosistema

Antes de FlatList, los desarrolladores usaban ListView, que requería configuración manual de reutilización de celdas. FlatList automatizó este proceso implementando renderizado por ventanas similar a RecyclerView en Android (2014) y UICollectionView en iOS (2012). En proyectos modernos, FlatList es el estándar de facto para cualquier lista.

Cómo funciona la virtualización de FlatList

La virtualización de FlatList es un mecanismo donde el componente renderiza solo los elementos que caen dentro del área visible de la pantalla, más un pequeño búfer a cada lado. Los elementos restantes no se crean en el DOM, ahorrando memoria y acelerando el renderizado.

Al desplazarse, FlatList reutiliza las celdas View ya creadas, reemplazando sus datos. Esto evita crear miles de Views para una lista de 10 000 elementos. El tamaño de búfer predeterminado es de 10 elementos arriba y abajo del área visible, pero se puede configurar mediante windowSize.

ParámetroPredeterminadoDescripción
windowSize21Número de páginas a renderizar (1 página = altura de pantalla)
initialNumToRender10Número de elementos en el primer renderizado
maxToRenderPerBatch10Máximo de elementos renderizados por lote
removeClippedSubviewsfalseEliminar Views fuera de la pantalla de la jerarquía

La configuración óptima de estos parámetros permite equilibrar la suavidad del desplazamiento y el consumo de memoria. Para listas con elementos grandes, se recomienda reducir windowSize a 5-7.

API y props principales de FlatList

La API de FlatList incluye un conjunto de props para configurar la visualización y el comportamiento de la lista. Las dos props obligatorias son data (matriz de datos) y renderItem (función de renderizado de elementos). keyExtractor mejora el rendimiento proporcionando una clave única para cada elemento.

js
import React from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';

const App = () => {
  const data = Array.from({ length: 100 }, (_, i) => ({
    id: i.toString(),
    title: `Item #${i + 1}`,
  }));

  return (
    <FlatList
      data={data}
      renderItem={({ item }) => (
        <View style={styles.item}>
          <Text>{item.title}</Text>
        </View>
      )}
      keyExtractor={item => item.id}
      ItemSeparatorComponent={() => <View style={styles.separator} />}
    />
  );
};

ItemSeparatorComponent agrega un separador entre elementos, ListHeaderComponent y ListFooterComponent agregan encabezado y pie de página a la lista. Esto permite crear diseños complejos sin envoltorios adicionales.

js
const styles = StyleSheet.create({
  item: {
    padding: 16,
    backgroundColor: '#fff',
    borderBottomWidth: 1,
    borderBottomColor: '#e0e0e0',
  },
  separator: {
    height: 1,
    backgroundColor: '#ccc',
  },
});

Optimización del rendimiento de FlatList

La optimización de FlatList es crítica para aplicaciones con cientos y miles de elementos. Sin una configuración adecuada, la lista puede retrasarse durante el desplazamiento, consumir memoria excesiva y provocar fallos en dispositivos de gama baja.

La primera regla es usar keyExtractor con identificadores únicos y estables. Usar índices como claves provoca una reutilización incorrecta de celdas y errores de estado. La segunda regla es envolver renderItem en useCallback y usar React.memo para el componente de elemento.

getItemLayout para altura fija

Si todos los elementos tienen la misma altura, getItemLayout permite que FlatList calcule la posición de desplazamiento sin medir componentes. Esto proporciona un gran aumento de rendimiento, especialmente al desplazarse a un índice específico.

js
const ITEM_HEIGHT = 80;

const getItemLayout = (data, index) => ({
  length: ITEM_HEIGHT,
  offset: ITEM_HEIGHT * index,
  index,
});

<FlatList
  data={data}
  getItemLayout={getItemLayout}
  renderItem={renderItem}
/FlatList>

useMemo para datos evita renderizaciones innecesarias. Si los datos provienen de una API, transfórmelos una vez y guárdelos en caché. Use React.memo para el componente de elemento para evitar renderizar elementos sin cambios.

Listas horizontales y carruseles

FlatList horizontal se crea agregando la prop horizontal={true}. La lista cambia la dirección de desplazamiento al eje X, lo que es útil para carruseles de productos, galerías de imágenes y menús horizontales.

En modo horizontal, es importante configurar correctamente snapToInterval y snapToAlignment para un desplazamiento paso a paso como en los carruseles nativos. El componente maneja automáticamente el momentum y la liberación del dedo, deteniéndose en el elemento más cercano.

js
<FlatList
  horizontal
  data={images}
  renderItem={renderItem}
  keyExtractor={item => item.id}
  showsHorizontalScrollIndicator={false}
  snapToInterval={CARD_WIDTH + GAP}
  snapToAlignment="start"
  decelerationRate="fast"
  pagingEnabled
  onViewableItemsChanged={onViewableItemsChanged}
/>

onViewableItemsChanged es una devolución de llamada que se activa cuando cambian los elementos visibles. Se usa para análisis, carga diferida de imágenes y activación de videos solo para tarjetas visibles.

Pull-to-refresh y carga infinita

Pull-to-refresh en FlatList se implementa mediante las props refreshing y onRefresh, que funcionan junto con un estado de carga. Al tirar de la lista hacia abajo, se llama a onRefresh, y el indicador refreshing bloquea las llamadas repetidas.

La carga infinita se configura mediante onEndReached, una devolución de llamada que se activa al acercarse al final de la lista. onEndReachedThreshold determina cuántos elementos antes del final se activa el evento. Generalmente se usa paginación basada en cursor.

js
const ListWithPagination = () => {
  const [data, setData] = React.useState([]);
  const [page, setPage] = React.useState(1);
  const [refreshing, setRefreshing] = React.useState(false);

  const loadMore = React.useCallback(async () => {
    const newData = await fetchPage(page);
    setData(prev => [...prev, ...newData]);
    setPage(p => p + 1);
  }, [page]);

  return (
    <FlatList
      data={data}
      renderItem={renderItem}
      keyExtractor={item => item.id}
      refreshing={refreshing}
      onRefresh={loadMore}
      onEndReached={loadMore}
      onEndReachedThreshold={0.5}
    />
  );
};

Importante: onEndReached puede llamarse varias veces. Agregue un indicador isLoading para bloquear solicitudes repetidas hasta que finalice la anterior. Use ActivityIndicator en ListFooterComponent para indicar la carga.

Preguntas frecuentes

¿En qué se diferencia FlatList de ScrollView?

FlatList usa virtualización: renderiza solo los elementos visibles, ahorrando memoria con grandes conjuntos de datos. ScrollView renderiza todos los hijos a la vez, adecuado solo para listas pequeñas de 20-30 elementos. FlatList es óptimo para 100+ elementos.

¿Cómo solucionar el parpadeo al actualizar datos de FlatList?

El parpadeo ocurre cuando cambia la referencia a la matriz de datos. Use extraData pasando la dependencia, o envuelva renderItem en React.memo. Para control total, use useMemo para estabilizar las referencias de datos.

¿Por qué FlatList no se desplaza dentro de otra vista de desplazamiento?

FlatList no está diseñado para anidarse dentro de ScrollView debido a conflictos de gestos. Soluciones: use FlatList con nestedScrollEnabled (Android), SectionList para secciones, o mueva el desplazamiento externo a FlatList mediante ListHeaderComponent.

¿Cómo animar la aparición de elementos en FlatList?

Use Animated API dentro de renderItem con un retraso basado en el índice. Al desplazarse, use onViewableItemsChanged para activar animaciones. Las bibliotecas react-native-reanimated y react-native-lottie simplifican la creación de animaciones de aparición complejas.

¿Qué es VirtualizedList y cómo se relaciona con FlatList?

VirtualizedList es el componente base de virtualización sobre el que se construyen FlatList y SectionList. FlatList es un envoltorio de VirtualizedList con una API simplificada para listas planas. VirtualizedList proporciona un control de nivel más bajo, pero rara vez se usa directamente.

Resumen

  • FlatList es el componente principal de React Native para listas de alto rendimiento con virtualización automática y reutilización de celdas
  • La virtualización renderiza solo los elementos visibles mediante windowSize e initialNumToRender, ahorrando memoria en grandes conjuntos de datos
  • Props obligatorias: data, renderItem y keyExtractor — garantizan el funcionamiento correcto de la lista
  • getItemLayout acelera el desplazamiento para elementos de altura fija, eliminando la medición dinámica
  • Las listas horizontales y carruseles se configuran mediante horizontal y snapToInterval para desplazamiento paso a paso
  • Pull-to-refresh y onEndReached implementan carga infinita con protección contra llamadas repetidas
  • React.memo y useCallback son obligatorios para renderItem — sin ellos, cada desplazamiento provoca el renderizado de todos los elementos

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también