Bird
Raised Fist0
React Nativemobile~20 mins

Infinite scrolling (onEndReached) in React Native - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Infinite Scrolling Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ ui_behavior
intermediate
2:00remaining
What happens when onEndReached triggers in this FlatList?
Consider this React Native FlatList component with an onEndReached handler that fetches more items. What will the user see after scrolling to the bottom once?
React Native
import React, { useState } from 'react';
import { FlatList, Text, View } from 'react-native';

export default function App() {
  const [items, setItems] = useState(Array.from({ length: 20 }, (_, i) => i + 1));

  const loadMore = () => {
    const newItems = Array.from({ length: 10 }, (_, i) => items.length + i + 1);
    setItems([...items, ...newItems]);
  };

  return (
    <FlatList
      data={items}
      keyExtractor={item => item.toString()}
      renderItem={({ item }) => <Text>{`Item ${item}`}</Text>}
      onEndReached={loadMore}
      onEndReachedThreshold={0.5}
    />
  );
}
ANothing happens because onEndReached is not called automatically.
BThe list will reset and show only the first 10 items again.
CThe list will add 10 more items at the bottom, so the user can scroll further down.
DThe list will crash because setItems is called inside onEndReached.
Attempts:
2 left
💡 Hint
Think about what the loadMore function does when called.
❓ lifecycle
intermediate
2:00remaining
Why might onEndReached fire multiple times rapidly in this example?
Look at this FlatList with onEndReached calling fetchMore. Why could the fetchMore function be called many times quickly when scrolling to the bottom?
React Native
import React, { useState } from 'react';
import { FlatList, Text } from 'react-native';

export default function App() {
  const [data, setData] = useState(Array.from({ length: 15 }, (_, i) => i + 1));

  const fetchMore = () => {
    const more = Array.from({ length: 5 }, (_, i) => data.length + i + 1);
    setData([...data, ...more]);
  };

  return (
    <FlatList
      data={data}
      keyExtractor={item => item.toString()}
      renderItem={({ item }) => <Text>{`Item ${item}`}</Text>}
      onEndReached={fetchMore}
      onEndReachedThreshold={0.1}
    />
  );
}
ABecause onEndReachedThreshold is set too high, so it never triggers.
BBecause onEndReached triggers every time the user scrolls near the bottom, and fetchMore updates state causing re-render, triggering onEndReached again immediately.
CBecause fetchMore is asynchronous and React Native queues multiple calls automatically.
DBecause FlatList requires a debounce function to work properly.
Attempts:
2 left
💡 Hint
Think about what happens when state updates inside onEndReached.
🔧 Debug
advanced
2:00remaining
What error occurs with this onEndReached handler?
This FlatList's onEndReached handler tries to fetch more data but causes an error. What error will this code produce?
React Native
import React, { useState } from 'react';
import { FlatList, Text } from 'react-native';

export default function App() {
  const [items, setItems] = useState([1, 2, 3]);

  const loadMore = () => {
    setItems(items.push(items.length + 1));
  };

  return (
    <FlatList
      data={items}
      keyExtractor={item => item.toString()}
      renderItem={({ item }) => <Text>{`Item ${item}`}</Text>}
      onEndReached={loadMore}
      onEndReachedThreshold={0.5}
    />
  );
}
ATypeError: setItems is called with a number instead of an array.
BSyntaxError: Missing parentheses in function call.
CRuntimeError: Infinite loop detected in onEndReached.
DNo error, the list updates correctly.
Attempts:
2 left
💡 Hint
Check what Array.push returns and what setItems expects.
🧠 Conceptual
advanced
2:00remaining
Which option best prevents multiple onEndReached calls during loading?
You want to avoid multiple fetches while loading more data in onEndReached. Which approach below correctly prevents multiple calls?
AUse a global variable outside the component to track calls.
BCall fetchMore inside a setTimeout with 0 delay to delay execution.
CRemove onEndReachedThreshold so onEndReached triggers only once.
DUse a loading state boolean to skip fetchMore if already loading, setting loading true before fetch and false after.
Attempts:
2 left
💡 Hint
Think about how to track if a fetch is in progress inside the component.
❓ navigation
expert
2:00remaining
What is the best way to reset FlatList scroll position after loading new data?
After loading more items in onEndReached, you want to reset the FlatList scroll to the top. Which method correctly achieves this?
React Native
import React, { useState, useRef } from 'react';
import { FlatList, Text, Button } from 'react-native';

export default function App() {
  const [data, setData] = useState(Array.from({ length: 20 }, (_, i) => i + 1));
  const listRef = useRef(null);

  const loadMore = () => {
    const more = Array.from({ length: 10 }, (_, i) => data.length + i + 1);
    setData([...data, ...more]);
    // Reset scroll here
  };

  return (
    <>
      <Button title="Load More and Scroll Top" onPress={loadMore} />
      <FlatList
        ref={listRef}
        data={data}
        keyExtractor={item => item.toString()}
        renderItem={({ item }) => <Text>{`Item ${item}`}</Text>}
      />
    </>
  );
}
ACall listRef.current.scrollToOffset({ offset: 0, animated: true }) right after setData in loadMore.
BCall listRef.current.scrollToIndex({ index: 0 }) before setData in loadMore.
CCall listRef.current.scrollToEnd() after setData in loadMore.
DUse FlatList's initialScrollIndex prop to 0 and update it after loading.
Attempts:
2 left
💡 Hint
Think about how to scroll programmatically after state updates.

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