Infinite scrolling lets users keep seeing more items as they scroll down without pressing buttons. It feels smooth and natural, like browsing a long list that never ends.
Infinite scrolling (onEndReached) in React Native
import { FlatList } from 'react-native'; <FlatList data={dataArray} renderItem={renderItemFunction} keyExtractor={item => item.id.toString()} onEndReached={loadMoreFunction} onEndReachedThreshold={0.5} />
onEndReached is a function called when the list scroll reaches near the end.
onEndReachedThreshold controls how close to the end the event triggers (0.5 means half the visible length before the end).
onEndReached={() => console.log('Load more items')}fetchMoreData when the user is 20% away from the bottom.<FlatList
onEndReached={fetchMoreData}
onEndReachedThreshold={0.2}
/><FlatList
onEndReached={() => setPage(page + 1)}
onEndReachedThreshold={1}
/>This example shows a list that loads 10 more items each time you scroll near the bottom. It uses a loading spinner while fetching.
import React, { useState, useEffect } from 'react'; import { View, Text, FlatList, ActivityIndicator } from 'react-native'; export default function InfiniteScrollExample() { const [data, setData] = useState([]); const [page, setPage] = useState(1); const [loading, setLoading] = useState(false); const fetchData = async () => { if (loading) return; setLoading(true); // Simulate fetching 10 new items setTimeout(() => { const newItems = Array.from({ length: 10 }, (_, i) => ({ id: (page - 1) * 10 + i + 1, title: `Item ${(page - 1) * 10 + i + 1}` })); setData(prev => [...prev, ...newItems]); setPage(prev => prev + 1); setLoading(false); }, 1000); }; useEffect(() => { fetchData(); }, []); const renderItem = ({ item }) => <Text style={{ padding: 20, borderBottomWidth: 1 }}>{item.title}</Text>; return ( <View style={{ flex: 1, marginTop: 50 }}> <FlatList data={data} renderItem={renderItem} keyExtractor={item => item.id.toString()} onEndReached={fetchData} onEndReachedThreshold={0.5} ListFooterComponent={loading ? <ActivityIndicator size="large" /> : null} /> </View> ); }
Make sure to prevent multiple loads at the same time by checking a loading state.
Adjust onEndReachedThreshold to control how early the loading starts.
Use unique keys for list items to avoid rendering issues.
Infinite scrolling loads more content automatically as the user scrolls.
Use onEndReached in FlatList to detect when to load more.
Manage loading state to avoid repeated calls and show a loading indicator.
Practice
What is the main purpose of the onEndReached prop in a React Native FlatList?
Solution
Step 1: Understand
This prop triggers a function when the user scrolls near the end of the list.onEndReachedroleStep 2: Compare with other options
Refreshing is handled byonRefresh, initial items byinitialNumToRender, and styling is unrelated.Final Answer:
To detect when the user scrolls near the end of the list to load more items -> Option AQuick Check:
onEndReachedtriggers loading more [OK]
- Confusing onEndReached with pull-to-refresh
- Thinking it controls initial render count
- Assuming it styles the list footer
Which of the following is the correct way to use onEndReached in a FlatList?
<FlatList
data={data}
renderItem={renderItem}
onEndReached={_____}
/>Solution
Step 1: Understand event handler syntax
onEndReachedexpects a function, so we pass a function reference or an arrow function.Step 2: Analyze options
onEndReached() ("onEndReached()") calls an undefined function immediately. loadMoreItems() ("loadMoreItems()") executes immediately on render. () => loadMoreItems ("() => loadMoreItems") returns the function but does not call it when triggered. loadMoreItems ("loadMoreItems") passes the correct function reference.Final Answer:
loadMoreItems -> Option DQuick Check:
Pass a function reference, not call it immediately [OK]
- Calling the function immediately instead of passing it
- Passing undefined or wrong function name
- Confusing function reference with function call
Given this code snippet, what will happen when the user scrolls near the end of the list?
const [items, setItems] = React.useState([1, 2, 3]);
const loadMore = () => {
setItems(prev => [...prev, prev.length + 1]);
};
return (
<FlatList
data={items}
renderItem={({item}) => <Text>Item {item}</Text>}
keyExtractor={item => item.toString()}
onEndReached={loadMore}
/>
);Solution
Step 1: Understand loadMore function
It adds a new item with value one greater than current length to the items array.Step 2: Analyze onEndReached effect
When user scrolls near the end,loadMoreis called, so items grow by one each time.Final Answer:
The list will add one new item each time the end is reached -> Option AQuick Check:
onEndReached triggers loadMore which appends items [OK]
- Thinking the list resets instead of appending
- Assuming loadMore is not called automatically
- Expecting a crash without seeing infinite state updates
What is the main problem with this infinite scrolling implementation?
const [items, setItems] = React.useState([1, 2, 3]);
const loadMore = () => {
setItems(prev => [...prev, prev.length + 1]);
};
return (
<FlatList
data={items}
renderItem={({item}) => <Text>Item {item}</Text>}
keyExtractor={item => item.toString()}
onEndReached={loadMore}
onEndReachedThreshold={0.1}
/>
);Assume the list is short and the user scrolls to the bottom.
Solution
Step 1: Understand onEndReached behavior
When the list is short, scrolling near the end triggersloadMorerepeatedly because the end is always near.Step 2: Identify consequence
This causes many state updates rapidly, which can cause performance problems or infinite loops.Final Answer:
loadMore will be called repeatedly causing many state updates and possible performance issues -> Option CQuick Check:
Repeated onEndReached calls cause performance issues [OK]
- Ignoring repeated calls without loading state
- Blaming keyExtractor or renderItem incorrectly
- Thinking threshold prevents repeated calls
You want to implement infinite scrolling with a loading spinner at the bottom. Which approach correctly prevents multiple loadMore calls while loading?
const [items, setItems] = React.useState([]);
const [loading, setLoading] = React.useState(false);
const loadMore = async () => {
if (loading) return;
setLoading(true);
const newItems = await fetchMoreItems();
setItems(prev => [...prev, ...newItems]);
setLoading(false);
};
return (
<FlatList
data={items}
renderItem={({item}) => <Text>{item}</Text>}
keyExtractor={item => item.id}
onEndReached={loadMore}
ListFooterComponent={loading ? <ActivityIndicator /> : null}
/>
);What is the key reason this works well?
Solution
Step 1: Identify loading state role
Theloadingstate preventsloadMorefrom running if a load is already in progress.Step 2: Understand async loading and UI feedback
While loading, the spinner shows in the footer, and new calls are blocked until loading finishes.Final Answer:
It uses a loading state to block new calls until the current load finishes -> Option BQuick Check:
Loading state blocks repeated calls during fetch [OK]
- Not blocking repeated calls causing multiple fetches
- Calling fetchMoreItems synchronously (wrong)
- Misusing ListFooterComponent to block scrolling
Ready to prove it?
Pass the test and this pattern moves unknown
