Belajar React Native - List, Scroll & Performance Dasar
Episode 8 of 23

Belajar React Native - List, Scroll & Performance Dasar

Episode ini membahas list dan scroll yang efisien: FlatList dan SectionList dengan keyExtractor, getItemLayout, dan windowing, onEndReached untuk infinite scroll, serta optimasi render dengan memo dan key yang stabil.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Feed media sosial, daftar produk, dan chat punya satu kesamaan: data yang panjangnya bisa ribuan item. Jika kalian me-render semuanya sekaligus, aplikasi akan tersendat karena memory dan UI Thread bekerja di luar kendali.

Episode 8 membahas cara menyajikan list panjang dengan efisien: FlatList dan SectionList dengan keyExtractor, getItemLayout, dan windowing, onEndReached untuk infinite scroll, lalu optimasi render dengan memo dan key yang stabil. Ini fondasi performa yang akan dilanjutkan di episode 18.

FlatList untuk Data Panjang

Mengapa Bukan ScrollView

ScrollView me-render semua anak sekaligus — cocok untuk konten statis dengan jumlah item sedikit. Untuk data panjang, pakai FlatList yang menerapkan virtualisasi: hanya item yang mendekati area tampil yang di-render, sisanya di-recycle saat di-scroll keluar.

JSFlatList dasar
import { FlatList, View, Text } from "react-native";
 
<FlatList
  data={posts}
  keyExtractor={(item) => item.id}
  renderItem={({ item }) => (
    <View style={{ padding: 16 }}>
      <Text>{item.title}</Text>
    </View>
  )}
  initialNumToRender={10}
  windowSize={5}
/>

initialNumToRender={10} mengontrol berapa item pertama yang dirender, dan windowSize menentukan berapa unit tinggi layar di sekitar area tampil yang tetap di-render. Keduanya membatasi kerja awal saat list dibuka.

keyExtractor dan Keys yang Stabil

keyExtractor memberi identitas unik tiap item. Tanpa key yang stabil, React kesulitan melacak item saat data berubah — scroll jadi melompat dan state item tertukar. Pakai id dari server, bukan index, karena index berubah saat item dihapus atau ditambah.

JSkeyExtractor memakai id server
keyExtractor={(item) => item.id}

getItemLayout untuk Lompatan Akurat

Jika semua item punya tinggi tetap, beri tahu FlatList lewat getItemLayout agar lompatan scroll seperti scroll-to-index bekerja akurat tanpa mengukur:

JSgetItemLayout untuk tinggi tetap
const ITEM_HEIGHT = 56;
 
getItemLayout={(_, index) => ({
  length: ITEM_HEIGHT,
  offset: ITEM_HEIGHT * index,
  index,
})}

SectionList dan Windowing

List dengan Section Header

SectionList menambahkan grup dan header di atas FlatList — cocok untuk daftar kontak per huruf atau produk per kategori:

JSSectionList dengan header
import { SectionList, Text } from "react-native";
 
<SectionList
  sections={[
    { title: "A", data: ["Apel", "Alpukat"] },
    { title: "B", data: ["Belimbing"] },
  ]}
  keyExtractor={(item, index) => item + index}
  renderItem={({ item }) => <Text>{item}</Text>}
  renderSectionHeader={({ section }) => <Text>{section.title}</Text>}
/>

Memilih jumlah Render Awal

SectionList menerima prop yang sama dengan FlatList: initialNumToRender, windowSize, dan maxToRenderPerBatch. Untuk ribuan item, kombinasi nilai kecil pada initialNumToRender dan wajar pada windowSize menjaga scroll tetap 60 fps.

Infinite Scroll dengan onEndReached

Pagination dengan Scroll

Pola umpan berita: muat halaman berikutnya saat user mendekati ujung list. onEndReached dipanggil ketika jarak scroll dari ujung kurang dari onEndReachedThreshold (fraksi dari panjang list):

JSInfinite scroll dengan pagination
const [halaman, setHalaman] = useState(1);
const [posts, setPosts] = useState([]);
 
function muatLagi() {
  setHalaman((p) => {
    ambilPostingan(p + 1).then((baru) => {
      setPosts((lama) => [...lama, ...baru]);
    });
    return p + 1;
  });
}
 
<FlatList
  data={posts}
  onEndReached={muatLagi}
  onEndReachedThreshold={0.5}
  ListFooterComponent={() => <Text>Memuat...</Text>}
/>

Hindari Request Ganda

onEndReached bisa terpanggil beberapa kali saat user menahan scroll di ujung. Beri penjaga agar request tidak duplikat — misalnya flag sedangMemuat yang hanya direset setelah respons datang.

Optimasi Render

memo untuk Item List

Setiap perubahan data parent me-render ulang seluruh anak. Bungkus item list dengan memo agar komponen hanya re-render saat props-nya berubah:

JSItem list dengan memo
import React, { memo } from "react";
import { Pressable, Text } from "react-native";
 
export const ItemList = memo(function ItemList({ item, onPress }) {
  return (
    <Pressable onPress={onPress}>
      <Text>{item.title}</Text>
    </Pressable>
  );
});

memo saja belum cukup jika prop onPress dibuat ulang setiap render. Stabilkan dengan useCallback — kita bahas di episode 5 — agar referensi fungsi sama antar render.

Fungsi Render yang Didefinisikan di Luar

Jangan menulis renderItem inline di dalam JSX jika tidak perlu. Fungsi baru setiap render menghilangkan manfaat memo. Definisikan renderItem di luar komponen atau bungkus dengan useCallback yang dependency-nya minimal.

Warning

Jangan pakai index sebagai key untuk list yang bisa disisipkan atau dihapus item-nya. Index berubah dan React menganggap item berpindah, menyebabkan state visual tertukar. Gunakan id unik dari data atau kombinasikan dengan field lain.

Penutup

Episode 8 membuat list panjang terasa ringan: FlatList dan SectionList dengan virtualisasi, keyExtractor dan getItemLayout untuk akurasi, onEndReached untuk infinite scroll, serta memo dan key stabil untuk mengurangi re-render.

Inti yang harus dibawa pulang:

  • ScrollView untuk konten pendek; FlatList untuk data panjang.
  • Virtualisasi hanya me-render item di sekitar area tampil.
  • Key harus stabil dan unik — gunakan id server, bukan index.
  • getItemLayout mempercepat lompatan scroll saat tinggi item tetap.
  • onEndReached untuk infinite scroll, lengkapi dengan penjaga request ganda.
  • memo dan useCallback memangkas re-render yang tidak perlu.

Di episode 9 selanjutnya kita akan membahas AsyncStorage dan local persistence: penyimpanan key-value dengan AsyncStorage, SQLite dan MMKV untuk data besar, enkripsi data sensitif, serta pola offline-first dengan queue dan strategi sinkronisasi.

Belajar React Native - List, Scroll & Performance Dasar | Belajar React Native