Lesson 105 of 158 – React Native FlatList with API Data
66%

React Native FlatList with API Data

FlatList is one of the most important React Native components for displaying lists of data. When a REST API returns many records, FlatList can display those records efficiently without rendering every item at the same time.

Note: In this lesson, we will learn how to fetch data from a PHP REST API and display it using FlatList in React Native.

1. What is FlatList?

FlatList is a React Native component designed to display a list of data.

<FlatList
    data={students}
    renderItem={({ item }) => (
        <Text>
            {item.name}
        </Text>
    )}
/>

It is especially useful when the application has many records.

2. Why Use FlatList for API Data?

  • Displays API records as a list.
  • Works well with large datasets.
  • Supports scrolling automatically.
  • Supports item separators.
  • Supports headers and footers.
  • Supports refreshing.
  • Supports pagination and infinite scrolling.

3. Import FlatList

import {
    FlatList
} from "react-native";

FlatList is included with React Native, so no external package is required.

4. FlatList Basic Structure

<FlatList
    data={students}

    renderItem={({ item }) => (
        <Text>
            {item.name}
        </Text>
    )}
/>

The two most important properties are data and renderItem.

5. The data Property

The data property contains the array that FlatList should display.

const students = [
    {
        id: 1,
        name: "Rahul"
    },
    {
        id: 2,
        name: "Amit"
    }
];
<FlatList
    data={students}
/>

6. The renderItem Property

renderItem tells FlatList how each record should be displayed.

<FlatList
    data={students}

    renderItem={({ item }) => (

        <Text>
            {item.name}
        </Text>

    )}
/>

7. Understanding item

The item variable represents the current record being rendered.

renderItem={({ item }) => (

    <Text>
        {item.name}
    </Text>

)}

If the current record is a student, item contains that student's data.

8. Display Multiple Student Fields

<FlatList
    data={students}

    renderItem={({ item }) => (

        <View>

            <Text>
                Name: {item.name}
            </Text>

            <Text>
                Email: {item.email}
            </Text>

            <Text>
                Course: {item.course}
            </Text>

        </View>

    )}
/>

9. keyExtractor

keyExtractor gives each FlatList item a stable key.

<FlatList
    data={students}

    keyExtractor={item =>
        item.id.toString()
    }

    renderItem={({ item }) => (
        <Text>
            {item.name}
        </Text>
    )}
/>

10. Fetch API Data for FlatList

const [students, setStudents] =
    useState([]);

async function loadStudents() {

    const response =
        await fetch(API_URL);

    const result =
        await response.json();

    setStudents(
        result.data || []
    );
}

The returned array can then be passed to FlatList.

11. FlatList with useEffect

useEffect(() => {

    loadStudents();

}, []);

This loads the API data when the screen is initially rendered.

12. Loading State with FlatList

if (loading) {

    return (
        <ActivityIndicator
            size="large"
        />
    );
}

return (
    <FlatList
        data={students}
        renderItem={renderStudent}
    />
);

13. Error State with FlatList

if (error) {

    return (
        <View>

            <Text>
                {error}
            </Text>

        </View>
    );
}

return (
    <FlatList
        data={students}
        renderItem={renderStudent}
    />
);

14. ListEmptyComponent

ListEmptyComponent displays content when the data array is empty.

<FlatList
    data={students}

    renderItem={renderStudent}

    ListEmptyComponent={
        <Text>
            No students found.
        </Text>
    }
/>

15. ItemSeparatorComponent

ItemSeparatorComponent can display a separator between list items.

function Separator() {

    return (
        <View
            style={{
                height: 1
            }}
        />
    );
}
<FlatList
    data={students}
    renderItem={renderStudent}
    ItemSeparatorComponent={
        Separator
    }
/>

16. ListHeaderComponent

ListHeaderComponent displays content above the list.

<FlatList
    data={students}

    renderItem={renderStudent}

    ListHeaderComponent={
        <Text>
            Student List
        </Text>
    }
/>

17. ListFooterComponent

ListFooterComponent displays content below the list.

<FlatList
    data={students}

    renderItem={renderStudent}

    ListFooterComponent={
        <Text>
            End of Student List
        </Text>
    }
/>

18. Refreshing FlatList Data

FlatList supports pull-to-refresh using the refreshing and onRefresh properties.

<FlatList
    data={students}

    renderItem={renderStudent}

    refreshing={loading}

    onRefresh={loadStudents}
/>

19. Refresh Control State

const [refreshing, setRefreshing] =
    useState(false);

async function refreshStudents() {

    setRefreshing(true);

    try {

        await loadStudents();

    } finally {

        setRefreshing(false);

    }
}

This separates refresh activity from other loading operations when needed.

20. Displaying a Student Card

function renderStudent({
    item
}) {

    return (

        <View>

            <Text>
                {item.name}
            </Text>

            <Text>
                {item.email}
            </Text>

            <Text>
                {item.course}
            </Text>

        </View>

    );
}

Keeping the item rendering logic in a separate function can make the FlatList easier to read.

21. FlatList with TypeScript

TypeScript can describe the structure of each API record.

interface Student {
    id: number;
    name: string;
    email: string;
    course: string;
}

const [students, setStudents] =
    useState<Student[]>([]);

22. Typed renderItem

const renderStudent = ({
    item
}: {
    item: Student
}) => {

    return (

        <View>

            <Text>
                {item.name}
            </Text>

            <Text>
                {item.email}
            </Text>

        </View>
    );
};

This helps TypeScript understand the structure of each list item.

23. FlatList and Search

API data can be filtered before it is displayed.

const filteredStudents =
    students.filter(student =>

        student.name
            .toLowerCase()
            .includes(search.toLowerCase())

    );
<FlatList
    data={filteredStudents}
    renderItem={renderStudent}
/>

24. FlatList and API Pagination

FlatList can request more API data when the user reaches the end of the list.

<FlatList
    data={students}

    renderItem={renderStudent}

    onEndReached={loadMore}

    onEndReachedThreshold={0.5}
/>

This is commonly used for infinite scrolling.

25. onEndReached

onEndReached runs when the list gets close to the end.

async function loadMore() {

    if (loadingMore) {
        return;
    }

    await fetchNextPage();

}

The API can then receive the next page number.

GET /api/students.php?page=2

26. Loading More Data

const [loadingMore,
    setLoadingMore] =
    useState(false);

async function loadMore() {

    if (loadingMore) {
        return;
    }

    setLoadingMore(true);

    try {

        const response =
            await fetch(
                `${API_URL}?page=${page + 1}`
            );

        const result =
            await response.json();

        if (result.success) {

            setStudents(
                current => [
                    ...current,
                    ...(result.data || [])
                ]
            );

            setPage(
                current => current + 1
            );
        }

    } finally {

        setLoadingMore(false);

    }
}

27. FlatList Footer Loading

When loading the next page, a footer spinner can be displayed.

ListFooterComponent={
    loadingMore ? (
        <ActivityIndicator
            size="small"
        />
    ) : null
}

This allows the user to continue seeing the existing records while more data is being loaded.

28. Complete FlatList API Example

import React, {
    useEffect,
    useState
} from "react";

import {
    View,
    Text,
    FlatList,
    ActivityIndicator
} from "react-native";

const API_URL =
    "https://example.com/api/students.php";

export default function StudentList() {

    const [students, setStudents] =
        useState([]);

    const [loading, setLoading] =
        useState(false);

    const [error, setError] =
        useState("");

    async function loadStudents() {

        setLoading(true);
        setError("");

        try {

            const response =
                await fetch(API_URL);

            const result =
                await response.json();

            if (!response.ok) {

                throw new Error(
                    result.message ||
                    "Unable to load students"
                );
            }

            if (!result.success) {

                throw new Error(
                    result.message ||
                    "API request failed"
                );
            }

            setStudents(
                result.data || []
            );

        } catch (error) {

            setError(
                error.message
            );

        } finally {

            setLoading(false);

        }
    }

    useEffect(() => {

        loadStudents();

    }, []);

    function renderStudent({
        item
    }) {

        return (

            <View>

                <Text>
                    Name: {item.name}
                </Text>

                <Text>
                    Email: {item.email}
                </Text>

                <Text>
                    Course: {item.course}
                </Text>

            </View>
        );
    }

    if (loading) {

        return (
            <View>

                <ActivityIndicator
                    size="large"
                />

                <Text>
                    Loading students...
                </Text>

            </View>
        );
    }

    if (error) {

        return (
            <View>

                <Text>
                    {error}
                </Text>

            </View>
        );
    }

    return (

        <FlatList
            data={students}

            keyExtractor={item =>
                item.id.toString()
            }

            renderItem={renderStudent}

            ItemSeparatorComponent={() => (
                <View
                    style={{
                        height: 1
                    }}
                />
            )}

            ListHeaderComponent={
                <Text>
                    Student List
                </Text>
            }

            ListEmptyComponent={
                <Text>
                    No students found.
                </Text>
            }

            onRefresh={loadStudents}

            refreshing={loading}
        />
    );
}

29. Common FlatList API Mistakes

  • Forgetting to provide the data property.
  • Forgetting renderItem.
  • Using the wrong API response property.
  • Not providing stable keys.
  • Trying to render an array directly inside Text.
  • Not handling loading state.
  • Not handling API errors.
  • Not handling an empty list.
  • Loading the same page repeatedly.
  • Not preventing duplicate pagination requests.
  • Using ScrollView for very large datasets unnecessarily.

30. Complete FlatList API Flow

React Native Screen
        ↓
     useEffect()
        ↓
      fetch()
        ↓
      PHP API
        ↓
      MySQL
        ↓
      JSON Data
        ↓
     setStudents()
        ↓
      FlatList
        ↓
   ┌──────┴────────┐
   ↓               ↓
Display Items   User Scrolls
                   ↓
             onEndReached
                   ↓
              Next Page
                   ↓
              API Request
                   ↓
              Add Items
                   ↓
              FlatList

This pattern is the foundation for displaying API-driven lists in React Native applications and can later be extended with search, filtering, sorting, and pagination.

📌 Key Points

  • FlatList is used to display lists efficiently in React Native.
  • The data property contains the records to display.
  • renderItem defines how each record is displayed.
  • Use keyExtractor for stable item keys.
  • FlatList works well with REST API data.
  • Use loading and error states around API requests.
  • Use ListEmptyComponent when no records are available.
  • Use onRefresh for pull-to-refresh functionality.
  • Use onEndReached for loading additional pages.
  • Use ListFooterComponent to show pagination loading.
  • FlatList can work with TypeScript interfaces.
  • FlatList can be combined with search, filtering, and pagination.

🧠 Quick Quiz

Question: Which FlatList property is used to specify the array of records that should be displayed?