React Native Academy · Lezione

Pull-to-refresh e caricamento di altri elementi

Implementi onRefresh con RefreshControl per consentire agli utenti di trascinare verso il basso e ricaricare i dati, quindi utilizzi onEndReached per recuperare la pagina successiva dei risultati.

Lezione 2 di 413 passaggi

Pull-to-refresh e caricamento di altri elementi è una lezione React Native Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento React Native Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso React Native Academy include 4 lezioni in totale.

Parti di questa lezione non sono ancora state tradotte e vengono mostrate in inglese.

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.

Gratis per iniziare

Impara JavaScript con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
30
Lezioni
120

Domande Frequenti

La lezione «Pull-to-refresh e caricamento di altri elementi» è gratuita?

Sì — il testo completo di «Pull-to-refresh e caricamento di altri elementi» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso React Native Academy, passa a CoddyKit PRO. Il corso React Native Academy include 4 lezioni in totale.

Cosa imparerò in «Pull-to-refresh e caricamento di altri elementi»?

Implementi onRefresh con RefreshControl per consentire agli utenti di trascinare verso il basso e ricaricare i dati, quindi utilizzi onEndReached per recuperare la pagina successiva dei risultati. Eserciti React Native Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare React Native Academy?

Non è richiesta alcuna esperienza precedente. React Native Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Pull-to-refresh e caricamento di altri elementi»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione React Native Academy?

Sì. Ogni lezione React Native Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Dati di FlatList, renderItem e keyExtractor
  2. Pull-to-refresh e caricamento di altri elementi
  3. SectionList con intestazioni
  4. Creazione di un’app con elenco dei contatti
← Torna a React Native Academy