Bird
Raised Fist0
React Nativemobile~15 mins

Infinite scrolling (onEndReached) in React Native - Deep Dive

Choose your learning style10 modes available
Overview - Infinite scrolling (onEndReached)
What is it?
Infinite scrolling is a way to load more content automatically when the user scrolls near the end of a list. In React Native, the onEndReached event triggers a function to fetch and show more items. This creates a smooth experience without needing buttons to load more. It helps apps handle large data without slowing down.
Why it matters
Without infinite scrolling, users must tap buttons or wait for full data loads, which feels slow and clunky. Infinite scrolling keeps users engaged by showing new content seamlessly as they explore. It saves device memory by loading data in chunks, improving app speed and user satisfaction.
Where it fits
Learners should know basic React Native components and state management before this. After mastering infinite scrolling, they can learn about pagination, caching data, and optimizing performance for large lists.
Mental Model
Core Idea
Infinite scrolling loads more data automatically when the user reaches the end of a list, creating a continuous browsing experience.
Think of it like...
It's like walking down a never-ending hallway where new rooms open up just as you approach the last door, so you never run out of places to explore.
List View
┌─────────────────────────┐
│ Item 1                  │
│ Item 2                  │
│ ...                     │
│ Item N-1                │
│ Item N (near end)       │ ← onEndReached triggers here
│ Loading more items...    │
└─────────────────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding FlatList Basics
🤔
Concept: Learn how FlatList displays a scrollable list of items in React Native.
FlatList is a component that efficiently renders a list of data. You provide it an array and a function to render each item. It handles scrolling and only renders visible items to save memory.
Result
You see a scrollable list of items on the screen.
Knowing FlatList basics is essential because infinite scrolling builds on its scrolling and rendering features.
2
FoundationState and Data Loading Basics
🤔
Concept: Manage list data using React state and load initial items.
Use useState to hold your list data. Initially load a small set of items. Render them with FlatList. This sets the stage for adding more data later.
Result
The app shows a list with initial items from state.
Understanding state-driven data lets you update the list dynamically when new items arrive.
3
IntermediateUsing onEndReached to Detect Scroll End
🤔Before reading on: do you think onEndReached triggers exactly at the last item or slightly before? Commit to your answer.
Concept: onEndReached fires when the user scrolls near the end of the list, not necessarily at the last item.
Add onEndReached prop to FlatList with a function to load more data. It triggers when the scroll position passes a threshold near the end. This helps pre-load data before the user hits the bottom.
Result
When scrolling near the bottom, the load more function runs automatically.
Knowing onEndReached triggers early helps avoid blank screens and keeps loading smooth.
4
IntermediateHandling Loading State and Preventing Multiple Calls
🤔Before reading on: do you think onEndReached can fire multiple times quickly? Commit to yes or no.
Concept: Manage a loading flag to avoid triggering multiple data fetches simultaneously.
Use a loading state variable. When loading starts, set it true. Ignore onEndReached calls while loading is true. Set it false after data loads. This prevents duplicate fetches and race conditions.
Result
The app loads more data only once per scroll end, avoiding overload.
Controlling loading state prevents bugs and wasted network calls.
5
IntermediateAppending New Data to Existing List
🤔
Concept: Add newly fetched items to the existing list state instead of replacing it.
When new data arrives, use setState(prev => [...prev, ...newData]) to append. This keeps old items visible and adds new ones at the bottom.
Result
The list grows longer as you scroll, showing all loaded items.
Appending data preserves user context and creates the infinite scroll effect.
6
AdvancedOptimizing onEndReached Threshold and Performance
🤔Before reading on: do you think setting onEndReachedThreshold too high or too low affects user experience? Commit to your answer.
Concept: Adjust onEndReachedThreshold to control how early loading triggers and optimize performance.
onEndReachedThreshold is a number between 0 and 1 representing how far from the end the event fires. Too high triggers too early, wasting resources. Too low causes loading delays and blank screens. Find a balance based on item size and network speed.
Result
Smooth loading with minimal waiting or wasted fetches.
Tuning threshold improves perceived app speed and resource use.
7
ExpertHandling Edge Cases and User Experience
🤔Before reading on: do you think infinite scrolling works well for all types of content? Commit to yes or no.
Concept: Consider cases like no more data, errors, and user control for best UX.
Show a message or stop loading when no more items exist. Handle fetch errors gracefully with retry options. Optionally add a manual 'Load More' button for user control. Combine infinite scroll with pull-to-refresh for full experience.
Result
Robust, user-friendly infinite scrolling that handles real-world scenarios.
Anticipating edge cases prevents frustration and improves app quality.
Under the Hood
FlatList tracks the scroll position and calculates how close the user is to the end. When the scroll offset passes a threshold near the bottom, it triggers onEndReached. This event lets the app fetch more data asynchronously and update the list state. FlatList then re-renders with new items, maintaining smooth scrolling by only rendering visible items.
Why designed this way?
Infinite scrolling was designed to improve user experience by avoiding manual pagination. React Native's FlatList uses onEndReached to balance performance and usability, triggering data loads early enough to prevent empty screens but not too early to waste resources. This design supports large datasets on limited mobile memory.
Scroll Position Tracking
┌─────────────────────────────┐
│ Scroll Event Listener        │
│                             │
│ ┌───────────────────────┐   │
│ │ Scroll Offset Check    │───┼─> If near end, trigger onEndReached
│ └───────────────────────┘   │
│                             │
│ ┌───────────────────────┐   │
│ │ Fetch More Data       │<───┼─ App fetches asynchronously
│ └───────────────────────┘   │
│                             │
│ ┌───────────────────────┐   │
│ │ Update List State     │<───┼─ Append new items
│ └───────────────────────┘   │
│                             │
│ ┌───────────────────────┐   │
│ │ FlatList Re-render    │<───┼─ Show new items
│ └───────────────────────┘   │
└─────────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does onEndReached fire only once when you hit the last item? Commit yes or no.
Common Belief:onEndReached fires only once exactly at the last item.
Tap to reveal reality
Reality:onEndReached fires when the scroll position passes a threshold near the end, which can happen multiple times during scrolling.
Why it matters:Assuming it fires once causes bugs like multiple fetches or missed loads.
Quick: Is infinite scrolling always better than pagination? Commit yes or no.
Common Belief:Infinite scrolling is always the best way to load lists.
Tap to reveal reality
Reality:Infinite scrolling can overwhelm users or cause performance issues; sometimes pagination or manual loading is better.
Why it matters:Choosing infinite scroll blindly can hurt usability and app stability.
Quick: Does setting onEndReachedThreshold to 0 mean loading triggers exactly at the end? Commit yes or no.
Common Belief:Setting onEndReachedThreshold to 0 triggers loading exactly at the last item.
Tap to reveal reality
Reality:A threshold of 0 may cause loading to trigger too late, causing blank screens or delays.
Why it matters:Misconfiguring threshold leads to poor user experience.
Quick: Can you ignore loading state when using onEndReached? Commit yes or no.
Common Belief:You don't need to manage loading state; onEndReached handles it automatically.
Tap to reveal reality
Reality:Without loading state, onEndReached can trigger multiple fetches simultaneously, causing bugs.
Why it matters:Ignoring loading state wastes network and causes UI glitches.
Expert Zone
1
onEndReached can fire multiple times rapidly if not throttled, so debouncing or loading flags are critical in production.
2
The perceived smoothness depends heavily on network speed and data size; prefetching strategies can improve UX.
3
Combining infinite scroll with pull-to-refresh requires careful state management to avoid conflicts.
When NOT to use
Avoid infinite scrolling for content where users need precise control or want to reach a footer quickly. Use pagination or manual 'Load More' buttons instead. Also, for very large datasets with complex filtering, server-driven pagination is better.
Production Patterns
Real apps use infinite scrolling with loading spinners, error handling, and caching. They often combine it with analytics to track user engagement and optimize thresholds dynamically. Some use libraries that abstract onEndReached for better performance and customization.
Connections
Pagination
Alternative approach to loading data in chunks
Understanding pagination helps decide when infinite scrolling is appropriate or when explicit page controls improve user experience.
Event-driven programming
onEndReached is an event callback triggered by user scroll actions
Knowing event-driven patterns clarifies how UI reacts asynchronously to user input and system state.
Human-computer interaction (HCI)
Infinite scrolling affects how users perceive and interact with content
HCI principles guide when infinite scrolling improves engagement or causes fatigue, informing better design choices.
Common Pitfalls
#1Triggering multiple data fetches simultaneously causing duplicated items and wasted network calls.
Wrong approach:const [loading, setLoading] = useState(false); const loadMore = () => { fetchData(); // no loading check };
Correct approach:const [loading, setLoading] = useState(false); const loadMore = () => { if (loading) return; setLoading(true); fetchData().then(() => setLoading(false)); };
Root cause:Not managing loading state allows onEndReached to call fetch repeatedly before previous fetch finishes.
#2Replacing list data instead of appending, causing list to reset and user to lose scroll position.
Wrong approach:setData(newData); // replaces old data
Correct approach:setData(prevData => [...prevData, ...newData]); // appends new items
Root cause:Misunderstanding that new data should be added to existing list, not overwrite it.
#3Setting onEndReachedThreshold too low causing loading to trigger too late and blank screens.
Wrong approach:
Correct approach:
Root cause:Not realizing threshold controls how early loading triggers before reaching end.
Key Takeaways
Infinite scrolling uses onEndReached to load more data automatically as users near the end of a list.
Managing loading state and appending data correctly prevents bugs and ensures smooth user experience.
Tuning onEndReachedThreshold balances early loading with resource efficiency for better performance.
Infinite scrolling is not always the best choice; consider user control and content type before using it.
Handling edge cases like no more data and errors is essential for production-ready infinite scrolling.

Practice

(1/5)
1.

What is the main purpose of the onEndReached prop in a React Native FlatList?

easy
A. To detect when the user scrolls near the end of the list to load more items
B. To refresh the list when the user pulls down
C. To set the initial number of items displayed
D. To style the list footer component

Solution

  1. Step 1: Understand onEndReached role

    This prop triggers a function when the user scrolls near the end of the list.
  2. Step 2: Compare with other options

    Refreshing is handled by onRefresh, initial items by initialNumToRender, and styling is unrelated.
  3. Final Answer:

    To detect when the user scrolls near the end of the list to load more items -> Option A
  4. Quick Check:

    onEndReached triggers loading more [OK]
Hint: Remember: onEndReached means near list end, load more [OK]
Common Mistakes:
  • Confusing onEndReached with pull-to-refresh
  • Thinking it controls initial render count
  • Assuming it styles the list footer
2.

Which of the following is the correct way to use onEndReached in a FlatList?

<FlatList
  data={data}
  renderItem={renderItem}
  onEndReached={_____}
/>
easy
A. onEndReached()
B. loadMoreItems()
C. () => loadMoreItems
D. loadMoreItems

Solution

  1. Step 1: Understand event handler syntax

    onEndReached expects a function, so we pass a function reference or an arrow function.
  2. 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.
  3. Final Answer:

    loadMoreItems -> Option D
  4. Quick Check:

    Pass a function reference, not call it immediately [OK]
Hint: Pass function reference `loadMoreItems`, not `loadMoreItems()` [OK]
Common Mistakes:
  • Calling the function immediately instead of passing it
  • Passing undefined or wrong function name
  • Confusing function reference with function call
3.

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}
  />
);
medium
A. The list will add one new item each time the end is reached
B. The list will reset to only one item
C. The list will not change because loadMore is not called
D. The app will crash due to infinite loop

Solution

  1. Step 1: Understand loadMore function

    It adds a new item with value one greater than current length to the items array.
  2. Step 2: Analyze onEndReached effect

    When user scrolls near the end, loadMore is called, so items grow by one each time.
  3. Final Answer:

    The list will add one new item each time the end is reached -> Option A
  4. Quick Check:

    onEndReached triggers loadMore which appends items [OK]
Hint: onEndReached calls loadMore, which adds one item [OK]
Common Mistakes:
  • Thinking the list resets instead of appending
  • Assuming loadMore is not called automatically
  • Expecting a crash without seeing infinite state updates
4.

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.

medium
A. The keyExtractor will cause duplicate keys error
B. The list will never load more items because onEndReachedThreshold is too low
C. loadMore will be called repeatedly causing many state updates and possible performance issues
D. The renderItem function is missing a return statement

Solution

  1. Step 1: Understand onEndReached behavior

    When the list is short, scrolling near the end triggers loadMore repeatedly because the end is always near.
  2. Step 2: Identify consequence

    This causes many state updates rapidly, which can cause performance problems or infinite loops.
  3. Final Answer:

    loadMore will be called repeatedly causing many state updates and possible performance issues -> Option C
  4. Quick Check:

    Repeated onEndReached calls cause performance issues [OK]
Hint: Short lists cause repeated onEndReached calls without loading guard [OK]
Common Mistakes:
  • Ignoring repeated calls without loading state
  • Blaming keyExtractor or renderItem incorrectly
  • Thinking threshold prevents repeated calls
5.

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?

hard
A. It uses ListFooterComponent to prevent scrolling
B. It uses a loading state to block new calls until the current load finishes
C. It resets items to empty before loading new ones
D. It calls fetchMoreItems synchronously to avoid delays

Solution

  1. Step 1: Identify loading state role

    The loading state prevents loadMore from running if a load is already in progress.
  2. Step 2: Understand async loading and UI feedback

    While loading, the spinner shows in the footer, and new calls are blocked until loading finishes.
  3. Final Answer:

    It uses a loading state to block new calls until the current load finishes -> Option B
  4. Quick Check:

    Loading state blocks repeated calls during fetch [OK]
Hint: Use loading flag to block repeated loads and show spinner [OK]
Common Mistakes:
  • Not blocking repeated calls causing multiple fetches
  • Calling fetchMoreItems synchronously (wrong)
  • Misusing ListFooterComponent to block scrolling
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard