Lesson 104 of 158 – Display API Data in React Native
66%

Display API Data in React Native

After receiving data from a REST API, a React Native application needs to display that data on the screen. In this lesson, we will learn how to fetch JSON data from a PHP REST API and display it using React Native components such as Text, View, FlatList, and ScrollView.

Note: A common mobile application flow is: Fetch API → Convert JSON → Store in State → Display Data.

1. What Does API Data Mean?

API data is information returned by the server. REST APIs commonly return this information in JSON format.

{
    "success": true,
    "data": [
        {
            "id": 1,
            "name": "Rahul"
        },
        {
            "id": 2,
            "name": "Amit"
        }
    ]
}

2. Basic API Data Flow

React Native
      ↓
    fetch()
      ↓
   PHP API
      ↓
    MySQL
      ↓
    JSON
      ↓
response.json()
      ↓
React Native State
      ↓
    UI Screen

3. Create State for API Data

useState can store the data received from the API.

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

An empty array is useful when the API will return a list of records.

4. Fetch API Data

const response = await fetch(
    API_URL
);

const result =
    await response.json();

console.log(result);

The response is converted from JSON into a JavaScript object.

5. Store API Data in State

const result =
    await response.json();

setStudents(
    result.data || []
);

Once the state changes, React Native re-renders the screen.

6. Display a Single Value

If the API returns one object, individual properties can be displayed using Text.

const [student, setStudent] =
    useState(null);

<Text>
    {student?.name}
</Text>

7. Display Multiple Properties

<Text>
    Name: {student?.name}
</Text>

<Text>
    Email: {student?.email}
</Text>

<Text>
    Course: {student?.course}
</Text>

The optional chaining operator helps prevent errors when student is initially null.

8. Display a List of Records

When the API returns many records, FlatList is commonly used.

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

9. Using keyExtractor

keyExtractor provides a stable key for each item in a FlatList.

<FlatList
    data={students}

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

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

10. Display Data in a View

<View>

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

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

</View>

View can be used to group related information.

11. Create a Student Card

renderItem={({ item }) => (

    <View>

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

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

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

    </View>

)}

This approach can be styled later to create a professional student card.

12. Display API Data with useEffect

useEffect(() => {

    loadStudents();

}, []);

The empty dependency array means the function runs when the component is initially mounted.

13. Complete API Loading Function

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"
            );
        }

        setStudents(
            result.data || []
        );

    } catch (error) {

        setError(
            error.message
        );

    } finally {

        setLoading(false);

    }
}

14. Display Loading State

if (loading) {

    return (
        <View>

            <ActivityIndicator
                size="large"
            />

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

        </View>
    );
}

15. Display Error State

if (error) {

    return (
        <View>

            <Text>
                {error}
            </Text>

        </View>
    );
}

Showing an error message is better than leaving the user with a blank screen.

16. Display Empty Data

{students.length === 0 ? (

    <Text>
        No students found.
    </Text>

) : (

    <FlatList
        data={students}
        renderItem={renderStudent}
    />

)}

17. Display API Data with ScrollView

ScrollView can be used for a smaller amount of data.

<ScrollView>

    {students.map(student => (

        <View key={student.id}>

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

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

        </View>

    ))}

</ScrollView>

FlatList is generally preferred for long lists because it is designed for efficient list rendering.

18. Display Nested API Data

API responses can contain nested objects.

{
    "id": 1,
    "name": "Rahul",
    "course": {
        "id": 5,
        "name": "React Native"
    }
}

React Native can access the nested property:

<Text>
    {student.course?.name}
</Text>

19. Display API Data Conditionally

{student?.name ? (

    <Text>
        Student: {student.name}
    </Text>

) : (

    <Text>
        Student information unavailable.
    </Text>

)}

Conditional rendering lets the application display different content depending on the available API data.

20. Refreshing Displayed API Data

After adding, updating, or deleting a record, the list can be refreshed.

async function refreshData() {

    await loadStudents();

}

Another option is to update the local state immediately after a successful CRUD operation.

21. Display Data After POST

const result =
    await response.json();

if (result.success) {

    setStudents([
        result.data,
        ...students
    ]);

}

This can add a newly created record to the beginning of an existing list.

22. Display Data After PUT

setStudents(
    students.map(student =>

        student.id === updatedStudent.id
            ? updatedStudent
            : student

    )
);

This updates the matching record in the local React Native state.

23. Display Data After DELETE

setStudents(
    students.filter(
        student =>
            student.id !== deletedId
    )
);

The deleted record is removed from the displayed list.

24. Display API Data with FlatList

<FlatList
    data={students}

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

    renderItem={({ item }) => (

        <View>

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

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

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

        </View>

    )}

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

25. API Data with Loading and Error States

if (loading) {

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

if (error) {

    return (
        <Text>
            {error}
        </Text>
    );
}

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

26. Displaying API Data with TypeScript

In a TypeScript React Native project, an interface can describe the API data structure.

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

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

TypeScript helps detect incorrect property names and data types.

27. Reusable Student Component

function StudentCard({
    student
}) {

    return (

        <View>

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

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

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

        </View>

    );
}

Reusable components make large React Native applications easier to maintain.

28. Complete API Data Display 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();

    }, []);

    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={({ item }) => (

                <View>

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

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

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

                </View>

            )}

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

29. Common API Display Mistakes

  • Forgetting to call response.json().
  • Using the wrong property name from the API response.
  • Trying to display an array directly inside Text.
  • Not storing API data in state.
  • Not handling loading state.
  • Not handling API errors.
  • Not handling an empty result.
  • Using unstable keys in FlatList.
  • Using ScrollView for very large lists unnecessarily.
  • Not updating local state after CRUD operations.
  • Not checking the API response structure.

30. Complete API Data Display Flow

React Native Screen
        ↓
     useEffect()
        ↓
      fetch()
        ↓
      PHP API
        ↓
      JSON Data
        ↓
  response.json()
        ↓
     setState()
        ↓
   React Re-render
        ↓
   ┌──────┴───────┐
   ↓              ↓
Single Object   Array Data
   ↓              ↓
  View          FlatList
   ↓              ↓
     Display Data
        ↓
     User Interface

This is the basic process used to display REST API data in React Native applications.

📌 Key Points

  • REST APIs commonly return data in JSON format.
  • Use response.json() to convert JSON into JavaScript data.
  • Use useState() to store API data.
  • Use Text and View to display individual records.
  • Use FlatList for displaying lists of records.
  • Use keyExtractor to provide stable list keys.
  • Handle loading, error, and empty-data states.
  • Update local state after POST, PUT, and DELETE operations.
  • Use TypeScript interfaces when working with typed React Native projects.
  • Reusable components make API-driven screens easier to maintain.

🧠 Quick Quiz

Question: Which React Native component is commonly used to efficiently display a list of API records?