Tarik untuk Menyegarkan dan Memuat Lebih Banyak
Implementasikan onRefresh dengan RefreshControl agar pengguna dapat menarik layar ke bawah untuk memuat ulang data, lalu gunakan onEndReached untuk mengambil halaman hasil berikutnya.
Tarik untuk Menyegarkan dan Memuat Lebih Banyak adalah pelajaran React Native Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar React Native Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus React Native Academy mencakup 4 pelajaran total.
Bagian dari pelajaran ini belum diterjemahkan dan ditampilkan dalam bahasa Inggris.
Why Pull-to-Refresh?
Pull-to-refresh is a mobile-native gesture where the user pulls the list downward to trigger a data reload. It signals to the app that new content should be fetched from the server. React Native's FlatList has built-in support for this gesture through the onRefresh and refreshing props.
The refreshing and onRefresh Props
FlatList's pull-to-refresh requires two props: refreshing (a boolean that shows or hides the spinner) and onRefresh (a callback that runs your data-fetch logic). Set refreshing to true when the fetch starts and back to false when it completes.
const [refreshing, setRefreshing] = useState(false);
const onRefresh = async () => {
setRefreshing(true);
await fetchData();
setRefreshing(false);
};
<FlatList
data={items}
renderItem={renderItem}
keyExtractor={(item) => item.id}
refreshing={refreshing}
onRefresh={onRefresh}
/>Using RefreshControl for Custom Styling
For more control over the spinner's appearance, use the refreshControl prop with a RefreshControl component. This lets you set the spinner's tintColor (iOS) and colors (Android), and even add a custom progressViewOffset for apps with fixed headers.
import { RefreshControl } from 'react-native';
<FlatList
data={items}
renderItem={renderItem}
keyExtractor={(item) => item.id}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={onRefresh}
tintColor='#6200ee'
colors={['#6200ee', '#03dac5']}
/>
}
/>Infinite Scroll with onEndReached
Infinite scroll (load more / pagination) fetches additional data when the user approaches the bottom of the list. FlatList fires the onEndReached callback when the user scrolls within onEndReachedThreshold of the end. A threshold of 0.5 triggers the callback when the user is halfway to the end.
const [page, setPage] = useState(1);
const [items, setItems] = useState([]);
const loadMore = async () => {
const newItems = await fetchPage(page + 1);
setItems(prev => [...prev, ...newItems]);
setPage(prev => prev + 1);
};
<FlatList
data={items}
renderItem={renderItem}
keyExtractor={(item) => item.id}
onEndReached={loadMore}
onEndReachedThreshold={0.5}
/>Preventing Duplicate Load Calls
onEndReached can fire multiple times in quick succession as the user scrolls. Guard against duplicate fetches with a loading flag. Check the flag at the start of your load function and return early if a fetch is already in progress. Reset the flag once the data is loaded.
const [loadingMore, setLoadingMore] = useState(false);
const loadMore = async () => {
if (loadingMore) return; // guard against duplicates
setLoadingMore(true);
const newItems = await fetchPage(page + 1);
setItems(prev => [...prev, ...newItems]);
setPage(prev => prev + 1);
setLoadingMore(false);
};Footer Spinner for Load More
Show an ActivityIndicator in the ListFooterComponent while the next page is loading. Hide it when all pages are loaded. This gives users a visual cue that more content is coming and prevents them from repeatedly scrolling to try to load more when it is already loading.
const renderFooter = () => {
if (!loadingMore) return null;
return <ActivityIndicator style={{ padding: 16 }} />;
};
<FlatList
data={items}
renderItem={renderItem}
keyExtractor={(item) => item.id}
onEndReached={loadMore}
onEndReachedThreshold={0.5}
ListFooterComponent={renderFooter}
/>Detecting End of Data
Keep a hasMore boolean in state. When your API returns fewer items than the page size, you know there are no more pages. Set hasMore to false and guard the loadMore function with this check. Also update the footer to show an 'End of list' message instead of a spinner.
const [hasMore, setHasMore] = useState(true);
const loadMore = async () => {
if (loadingMore || !hasMore) return;
setLoadingMore(true);
const newItems = await fetchPage(page + 1);
if (newItems.length < PAGE_SIZE) setHasMore(false);
setItems(prev => [...prev, ...newItems]);
setPage(prev => prev + 1);
setLoadingMore(false);
};Combining Refresh and Load More
Pull-to-refresh and load more can coexist in the same FlatList. On refresh, reset the page to 1, clear the existing items, fetch the first page, and reset hasMore to true. The two flows are independent and use separate loading states so they do not interfere with each other.
const onRefresh = async () => {
setRefreshing(true);
setPage(1);
setHasMore(true);
const freshData = await fetchPage(1);
setItems(freshData);
setRefreshing(false);
};onEndReachedThreshold Best Practices
The onEndReachedThreshold value is a fraction of the visible list height, not a pixel value. Setting it to 0.2 triggers loading when 20% of the list content remains visible below the screen. A higher value starts loading earlier for slower APIs; a lower value is better for fast API responses.
// Trigger load more when 20% of list remains
<FlatList
onEndReached={loadMore}
onEndReachedThreshold={0.2}
/>Scroll Position After Refresh
After a refresh replaces the data array, FlatList may retain the old scroll position, making the new content invisible. Call flatListRef.current.scrollToOffset({ offset: 0, animated: true }) after setting fresh data to bring the list back to the top for a polished user experience.
const flatListRef = useRef(null);
const onRefresh = async () => {
setRefreshing(true);
const freshData = await fetchPage(1);
setItems(freshData);
flatListRef.current?.scrollToOffset({ offset: 0, animated: true });
setRefreshing(false);
};Testing Pull-to-Refresh on Emulator
On iOS Simulator, pull-to-refresh works with a trackpad two-finger swipe down on the list. On Android Emulator, click and drag down from a list item. On a physical device, the gesture is natural. Always test both platforms because iOS uses a native spinner while Android uses its own Material-style indicator.
Quick Check
Test your understanding of pull-to-refresh and infinite scroll from this lesson.
Lesson Recap
In this lesson you learned: use the refreshing and onRefresh props to implement pull-to-refresh, use onEndReached with onEndReachedThreshold for infinite scroll, and guard loadMore with a loading flag to prevent duplicate API calls. Next up we explore SectionList for grouped data with headers.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Tarik untuk Menyegarkan dan Memuat Lebih Banyak” gratis?
Ya — teks lengkap “Tarik untuk Menyegarkan dan Memuat Lebih Banyak” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus React Native Academy, upgrade ke CoddyKit PRO. Kursus React Native Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Tarik untuk Menyegarkan dan Memuat Lebih Banyak”?
Implementasikan onRefresh dengan RefreshControl agar pengguna dapat menarik layar ke bawah untuk memuat ulang data, lalu gunakan onEndReached untuk mengambil halaman hasil berikutnya. Kamu berlatih React Native Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai React Native Academy?
Tidak diperlukan pengalaman sebelumnya. React Native Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Tarik untuk Menyegarkan dan Memuat Lebih Banyak” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran React Native Academy ini?
Ya. Setiap pelajaran React Native Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Data FlatList, renderItem, dan keyExtractor
- Tarik untuk Menyegarkan dan Memuat Lebih Banyak
- SectionList dengan Header
- Membangun Aplikasi Daftar Kontak