Skip to main content
React Native Introduction
CHAPTER 12 Beginner

Lists and ScrollView in React Native

Updated: May 16, 2026
5 min read

# CHAPTER 12

Lists and ScrollView in React Native

1. Introduction

By default, mobile screens do not scroll. If you render 20 <Text> items inside a standard <View>, the items at the bottom will simply bleed off the edge of the physical screen and become entirely inaccessible. If you are building an Instagram feed or an e-commerce catalog, you need scrolling capabilities. In this chapter, we will master Lists and ScrollView. We will learn when to use the simple ScrollView wrapper for static pages, and when it is absolutely mandatory to use the highly-optimized FlatList component to render massive arrays of dynamic data without melting the phone's battery.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Implement a basic ScrollView for small, static content screens.
  • Understand the catastrophic memory issues of mapping large arrays inside a ScrollView.
  • Implement a FlatList for massive, dynamic datasets.
  • Utilize the data, renderItem, and keyExtractor props.
  • Build a structured SectionList for categorized data.

3. The ScrollView Component

ScrollView is the easiest way to make a screen scrollable. You simply replace your parent <View> with a <ScrollView>. It is perfect for a "Terms of Service" text page, or a User Profile screen with a dozen static elements.
javascript
12345678910111213141516
import React from &#039;react&#039;;
import { ScrollView, Text, View } from &#039;react-native&#039;;

export default function TermsScreen() {
  return (
    // Replaced View with ScrollView!
    <ScrollView style={{ padding: 20 }}> 
      <Text style={{ fontSize: 30 }}>Terms of Service</Text>
      <View style={{ height: 1000, backgroundColor: &#039;lightgrey&#039;, marginVertical: 20 }}>
        {/* Massive tall box representing lots of text */}
        <Text>Scroll down to read more...</Text>
      </View>
      <Text>End of Terms.</Text>
    </ScrollView>
  );
}

4. The ScrollView Memory Trap

If you have an array of 5,000 product objects, you might be tempted to use .map() inside a ScrollView to render 5,000 <ProductCard> components. DO NOT DO THIS. ScrollView renders *everything* inside it immediately. If you feed it 5,000 items, the React engine will try to calculate and draw 5,000 heavy UI components at the exact same millisecond. The app will freeze, RAM will spike to 100%, and the OS will crash the app.

5. The Solution: FlatList

For dynamic arrays, you MUST use FlatList. FlatList is incredibly smart. It uses "Lazy Rendering." If you give it 5,000 items, it only draws the 10 items currently visible on the glass screen. As the user scrolls down, it destroys the top items and dynamically draws the new bottom items. The RAM usage stays perfectly flat at 10 items, no matter how large the array is!

6. Using FlatList (The 3 Core Props)

FlatList requires exactly three properties to function:
  1. 1. data: The raw JavaScript array (the 5,000 objects).
  1. 2. renderItem: A function that explains *how* to draw one single object from that array.
  1. 3. keyExtractor: A function that tells React how to find the unique ID of each object.
javascript
1234567891011121314151617181920212223242526272829303132333435363738
import React from &#039;react&#039;;
import { FlatList, Text, View, StyleSheet } from &#039;react-native&#039;;

// 1. The Raw Data Array
const PRODUCTS = [
  { id: &#039;1&#039;, title: &#039;Laptop&#039;, price: &#039;$999&#039; },
  { id: &#039;2&#039;, title: &#039;Phone&#039;, price: &#039;$699&#039; },
  { id: &#039;3&#039;, title: &#039;Tablet&#039;, price: &#039;$499&#039; },
  // ... imagine 5,000 more items here
];

export default function StoreScreen() {
  
  // 2. The Render Function (Destructures the single 'item' from the array)
  const renderProductCard = ({ item }) => (
    <View style={styles.card}>
      <Text style={styles.title}>{item.title}</Text>
      <Text style={styles.price}>{item.price}</Text>
    </View>
  );

  return (
    <View style={styles.container}>
      <FlatList
        data={PRODUCTS} // Pass the array
        renderItem={renderProductCard} // Pass the UI blueprint
        keyExtractor={item => item.id} // Tell it where the unique ID is!
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: &#039;#f0f0f0&#039; },
  card: { backgroundColor: &#039;white&#039;, padding: 20, margin: 10, borderRadius: 8 },
  title: { fontSize: 18, fontWeight: &#039;bold&#039; },
  price: { color: &#039;green&#039;, marginTop: 5 }
});

7. SectionList (Categorized Data)

What if you want a list with sticky headers, like "A", "B", "C" in a Contacts app? Use SectionList! It expects the data array to be formatted with title and data properties.
javascript
123456789101112131415
const MENU_DATA = [
  { title: &#039;Main Courses&#039;, data: [&#039;Pizza&#039;, &#039;Burger&#039;, &#039;Steak&#039;] },
  { title: &#039;Desserts&#039;, data: [&#039;Ice Cream&#039;, &#039;Cake&#039;] },
];

<SectionList
  sections={MENU_DATA}
  keyExtractor={(item, index) => item + index}
  // Renders the individual item
  renderItem={({ item }) => <Text style={styles.item}>{item}</Text>}
  // Renders the bold Header!
  renderSectionHeader={({ section: { title } }) => (
    <Text style={styles.header}>{title}</Text>
  )}
/>

8. Visual Learning: FlatList Lazy Rendering

txt
123456789101112
[ RAW ARRAY: 5000 Items ]
        |
   (FlatList engine reads data)
        |
[ PHONE SCREEN VISIBLE AREA ]
+-------------------------+
| [ Rendered Item 1 ]     | <-- Top item is about to scroll off.
| [ Rendered Item 2 ]     |
| [ Rendered Item 3 ]     |
+-------------------------+
| [ Rendered Item 4 ]     | <-- Item 4 is created JUST as it enters the screen.
| [ (Items 5-5000)  ]     | <-- NOT RENDERED YET. RAM IS SAVED.

9. Common Mistakes

  • Forgetting Destructuring in renderItem: The renderItem function does NOT just pass the raw object. It passes a wrapper object containing layout data, indices, AND your item.
BAD: renderItem={(item) => <Text>{item.title}</Text>} (Crash: item.title is undefined). GOOD: renderItem={({ item }) => <Text>{item.title}</Text>} (Notice the {} destructuring to pull the actual object out of the wrapper!).

10. Best Practices

  • Never nest Virtualized Lists: Never put a FlatList directly inside a ScrollView. They both contain complex scrolling math engines. They will fight each other, resulting in erratic scrolling behavior and console warnings. FlatList scrolls by itself automatically; it does not need a parent ScrollView.

11. Practice Exercises

  1. 1. What specific prop in a FlatList tells React how to uniquely identify each row so it can efficiently update or delete items without redrawing the whole list?
  1. 2. Write the syntax required to render an array of strings ['Apple', 'Banana'] into a FlatList.

12. MCQs with Answers

Question 1

Why is it an architectural disaster to use a .map() function inside a <ScrollView> to render an array of 10,000 complex data objects?

Question 2

Which required property of the <FlatList> component is responsible for providing the actual visual JSX template (the UI) that dictates how a single object from the array should look on the screen?

13. Interview Questions

  • Q: Explain the mechanical difference between standard rendering in a ScrollView versus virtualized, lazy rendering in a FlatList.
  • Q: Describe the specific purpose of the keyExtractor prop in a FlatList. How does React utilize these unique keys during the reconciliation phase when a list item is deleted?
  • Q: A developer has nested a vertical FlatList directly inside a vertical ScrollView. Explain why the React Native engine issues a severe warning against this pattern and what UI bugs it creates.

14. FAQs

Q: Can I pull down to refresh a FlatList like in Twitter? A: Yes! FlatList has built-in props exactly for this. Just add onRefresh={myRefreshFunction} and refreshing={isLoadingBool}. A native spinning wheel will automatically appear when the user pulls down from the top!

15. Summary

In Chapter 12, we mastered scrollable interfaces and infinite feeds. We utilized the basic ScrollView wrapper to permit scrolling on small, static detail screens. More importantly, we averted catastrophic memory leaks by leveraging the highly-optimized FlatList component for dynamic data arrays. We mastered its triad of core properties—passing raw arrays to data, designing UI blueprints within renderItem, and enforcing strict memory mapping via keyExtractor.

16. Next Chapter Recommendation

Our lists are rendering beautifully. Now we need a way for the user to add new items to those lists by typing text. Proceed to Chapter 13: User Input and Forms.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·