Inicio > Cursos > React Native > FlatList y Performance
React NativeReact Native AvanzadoLección 6 de 14

FlatList y Performance

FlatList es el componente de lista virtualizada de React Native. La virtualización significa que solo renderiza los elementos actualmente visibles en pantalla más un pequeño buffer. Si tienes 10.000 items, FlatList renderiza solo los ~20 visibles en pantalla, no los 10.000. Cuando el usuario hace scroll, destruye los elementos que salen de la pantalla y crea los nuevos que entran. Esto hace que listas enormes funcionen fluidamente con poca memoria.

FlatList requiere tres props principales: data (el array de datos), renderItem (función que recibe un item y devuelve el componente a renderizar), y keyExtractor (función que devuelve un ID único para cada item, necesario para la virtualización). Para separadores entre items usa ItemSeparatorComponent. Para la cabecera usa ListHeaderComponent. Para secciones agrupadas (como contactos por letra) usa SectionList. Si tienes pocas decenas de items, ScrollView con un map() es más simple.

import { FlatList, View, Text, RefreshControl } from "react-native";
import { useState, useCallback } from "react";

const DATOS = Array.from({ length: 1000 }, (_, i) => ({
  id: String(i),
  nombre: `Usuario ${i}`,
  puntos: Math.floor(Math.random() * 1000),
}));

function Tarjeta({ item, onPress }) {
  return (
    <TouchableOpacity onPress={() => onPress(item)} style={styles.tarjeta}>
      <Text style={styles.nombre}>{item.nombre}</Text>
      <Text style={styles.puntos}>{item.puntos} XP</Text>
    </TouchableOpacity>
  );
}

export default function ListaUsuarios() {
  const [refrescando, setRefrescando] = useState(false);
  
  // useCallback evita recrear la función en cada render
  const renderItem = useCallback(({ item }) => (
    <Tarjeta item={item} onPress={(u) => console.log(u)} />
  ), []);
  
  const keyExtractor = useCallback((item) => item.id, []);
  
  const onRefresh = useCallback(async () => {
    setRefrescando(true);
    await new Promise(r => setTimeout(r, 1500)); // Simula fetch
    setRefrescando(false);
  }, []);
  
  return (
    <FlatList
      data={DATOS}
      keyExtractor={keyExtractor}
      renderItem={renderItem}
      // Optimizaciones
      getItemLayout={(_, index) => ({
        length: 60, offset: 60 * index, index
      })}
      initialNumToRender={15}
      maxToRenderPerBatch={10}
      windowSize={5}
      // Pull to refresh
      refreshControl={
        <RefreshControl
          refreshing={refrescando}
          onRefresh={onRefresh}
          tintColor="#00E5A0"
        />
      }
      // Separador
      ItemSeparatorComponent={() => <View style={{ height: 1, backgroundColor: "#333" }} />}
    />
  );
}
Consejo⚡ Si conoces la altura fija de cada item, usa getItemLayout. FlatList puede calcular posiciones sin medir cada elemento, haciéndola mucho más rápida.
← Estado y AsyncStorageAnimaciones con Reanimated →

Practica esta lección

Resuelve los ejercicios del curso de React Native en la app, gratis y con corrección automática.

Empezar a practicar