FlatList: co to jest, API i optymalizacja w React Native

Autor: IT Sectr Opublikowano: 2026-07-05 Czas czytania: 10 min

FlatList — podstawowy komponent React Native do wyświetlania wydajnych list z wirtualizacją elementów. W przeciwieństwie do ScrollView, FlatList renderuje tylko widoczne elementy ekranu, oszczędzając pamięć i procesor. Komponent obsługuje przewijanie poziome i pionowe, pull-to-refresh oraz nieskończone ładowanie. Więcej o architekturze list przeczytasz w dokumentacji Meta.

Najważniejsze

  • FlatList — wirtualizowany komponent listy, który renderuje tylko widoczne elementy i ponownie je wykorzystuje podczas przewijania
  • Wydajność osiągana jest dzięki renderowaniu okienkowemu (windowing) — elementy poza ekranem nie są tworzone
  • API obejmuje renderItem, keyExtractor, ItemSeparatorComponent, ListHeaderComponent i ListFooterComponent
  • Listy poziome konfiguruje się za pomocą flagi horizontal, zmieniając kierunek przewijania na oś X
  • Optymalizacja wymaga prawidłowej konfiguracji keyExtractor, useMemo dla danych oraz getItemLayout dla stałych rozmiarów

Czym jest FlatList?

FlatList — komponent React Native implementujący wirtualizowaną listę z wydajnym renderowaniem dużych ilości danych. Komponent jest zbudowany na bazie VirtualizedList i udostępnia deklaratywne API do tworzenia płaskich list o dowolnym stopniu złożoności.

FlatList pojawił się w React Native 0.43 jako zamiennik przestarzałego ListView. Według danych Meta (2026), FlatList jest używany w 85% aplikacji React Native pracujących z listami. Komponent obsługuje wszystkie popularne scenariusze: kontakty, kanały informacyjne, katalogi produktów, czaty.

Historia i miejsce w ekosystemie

Przed pojawieniem się FlatList programiści używali ListView, który wymagał ręcznej konfiguracji ponownego wykorzystania komórek. FlatList zautomatyzował ten proces, wprowadzając renderowanie okienkowe na wzór RecyclerView w Androidzie (2014) i UICollectionView w iOS (2012). W nowoczesnych projektach FlatList jest standardem de facto dla wszystkich list.

Jak działa wirtualizacja FlatList

Wirtualizacja FlatList — mechanizm, w którym komponent renderuje tylko te elementy, które znajdują się w widocznym obszarze ekranu, plus niewielki bufor po każdej stronie. Pozostałe elementy nie są tworzone w DOM, co oszczędza pamięć i przyspiesza renderowanie.

Podczas przewijania FlatList ponownie wykorzystuje już utworzone widoki View, zastępując w nich dane. Zapobiega to tworzeniu tysięcy widoków dla listy 10 000 elementów. Domyślny rozmiar bufora to 10 elementów powyżej i poniżej widocznego obszaru, ale można go skonfigurować za pomocą windowSize.

ParametrDomyślnieOpis
windowSize21Liczba stron do renderowania (1 strona = wysokość ekranu)
initialNumToRender10Liczba elementów przy pierwszym renderowaniu
maxToRenderPerBatch10Maksymalna liczba elementów renderowanych w jednej partii
removeClippedSubviewsfalseUsuwanie widoków poza ekranem z hierarchii

Optymalna konfiguracja tych parametrów pozwala zrównoważyć płynność przewijania i zużycie pamięci. W przypadku list z dużymi elementami zaleca się zmniejszenie windowSize do 5-7.

API i główne właściwości FlatList

FlatList API obejmuje zestaw właściwości do konfiguracji wyglądu i zachowania listy. Dwie obowiązkowe właściwości to data (tablica danych) i renderItem (funkcja renderowania elementu). keyExtractor zwiększa wydajność, dostarczając unikalny klucz dla każdego elementu.

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 dodaje separator między elementami, ListHeaderComponent i ListFooterComponent — nagłówek i stopkę listy. Umożliwia to tworzenie złożonych układów bez dodatkowego opakowania.

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

Optymalizacja wydajności FlatList

Optymalizacja FlatList jest krytycznie ważna dla aplikacji z setkami i tysiącami elementów. Bez prawidłowej konfiguracji lista może działać wolno podczas przewijania, zużywać nadmierną pamięć i powodować awarie na słabszych urządzeniach.

Pierwszą zasadą jest używanie keyExtractor z unikalnymi i stabilnymi identyfikatorami. Indeksy jako klucze prowadzą do nieprawidłowego ponownego wykorzystania komórek i błędów stanu. Drugą — owijanie renderItem w useCallback i używanie React.memo dla komponentu elementu.

getItemLayout dla stałej wysokości

Jeśli wszystkie elementy mają tę samą wysokość, getItemLayout pozwala FlatList obliczać pozycję przewijania bez mierzenia komponentów. Daje to znaczący wzrost wydajności, szczególnie podczas przewijania do określonego indeksu.

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 dla danych zapobiega zbędnym przerenderowaniom. Jeśli dane pochodzą z API, przetwórz je raz i zapisz w pamięci podręcznej. Używaj React.memo dla komponentu elementu, aby uniknąć renderowania niezmienionych elementów.

Listy poziome i karuzele

Poziomy FlatList tworzy się przez dodanie właściwości horizontal={true}. Lista zmienia kierunek przewijania na oś X, co jest wygodne dla karuzel produktów, galerii obrazów i poziomych menu.

W trybie poziomym ważne jest prawidłowe skonfigurowanie snapToInterval i snapToAlignment dla krokowego przewijania, jak w natywnych karuzelach. Komponent automatycznie obsługuje pęd i puszczanie palca, zatrzymując się na najbliższym elemencie.

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 — callback wywoływany przy zmianie widocznych elementów. Używany do analityki, leniwego ładowania obrazów i aktywacji wideo tylko dla widocznych kart.

Pull-to-refresh i nieskończone ładowanie

Pull-to-refresh w FlatList implementuje się za pomocą właściwości refreshing i onRefresh, działających w parze ze stanem ładowania. Przy przeciągnięciu listy w dół wywoływany jest onRefresh, a flaga refreshing blokuje ponowne wywołania.

Nieskończone ładowanie (infinite scroll) konfiguruje się przez onEndReached — callback wyzwalany przy zbliżaniu się do końca listy. onEndReachedThreshold określa, ile elementów przed końcem wyzwala zdarzenie. Do paginacji zwykle stosuje się podejście cursor-based.

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

Ważne: onEndReached może być wywoływany wielokrotnie. Dodaj flagę isLoading, aby blokować powtarzające się żądania, dopóki poprzednie się nie zakończy. Użyj ActivityIndicator w ListFooterComponent do wskazania ładowania.

Często zadawane pytania

Czym FlatList różni się od ScrollView?

FlatList używa wirtualizacji — renderuje tylko widoczne elementy, co oszczędza pamięć przy dużych danych. ScrollView renderuje wszystkie elementy potomne od razu, nadaje się tylko do małych list do 20-30 elementów. FlatList jest optymalny dla 100+ elementów.

Jak naprawić migotanie (flash) podczas aktualizacji danych FlatList?

Migotanie występuje przy zmianie referencji tablicy data. Użyj extraData, przekazując tam zależność, lub owijaj renderItem w React.memo. Do pełnej kontroli stosuj useMemo do stabilizacji referencji danych.

Dlaczego FlatList nie przewija się wewnątrz innego scroll-widoku?

FlatList nie jest przeznaczony do zagnieżdżania w ScrollView z powodu konfliktu gestów. Rozwiązania: użyj FlatList z nestedScrollEnabled (Android), SectionList dla sekcji lub wynieś zewnętrzne przewijanie do FlatList przez ListHeaderComponent.

Jak animować pojawianie się elementów FlatList?

Użyj Animated API wewnątrz renderItem z opóźnieniem na podstawie indeksu. Podczas przewijania stosuj onViewableItemsChanged do wyzwalania animacji. Biblioteki react-native-reanimated i react-native-lottie ułatwiają tworzenie złożonych animacji pojawiania się.

Czym jest VirtualizedList i jak jest powiązany z FlatList?

VirtualizedList — podstawowy komponent wirtualizacji, na którym zbudowane są FlatList i SectionList. FlatList to otoczka VirtualizedList z uproszczonym API dla płaskich list. VirtualizedList zapewnia bardziej niskopoziomową kontrolę, ale rzadko jest używany bezpośrednio.

Podsumowanie

  • FlatList — podstawowy komponent React Native do wydajnych list z automatyczną wirtualizacją i ponownym wykorzystaniem komórek
  • Wirtualizacja renderuje tylko widoczne elementy przez windowSize i initialNumToRender, oszczędzając pamięć na dużych zbiorach danych
  • Obowiązkowe właściwości: data, renderItem i keyExtractor — zapewniają prawidłowe działanie listy
  • getItemLayout przyspiesza przewijanie dla elementów o stałej wysokości, eliminując dynamiczne mierzenie
  • Listy poziome i karuzele konfiguruje się przez horizontal i snapToInterval dla krokowego przewijania
  • Pull-to-refresh i onEndReached implementują nieskończone ładowanie z ochroną przed ponownymi wywołaniami
  • React.memo i useCallback są obowiązkowe dla renderItem — bez nich każde przewinięcie powoduje przerenderowanie wszystkich elementów

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również