Lesson 151 of 158 – Project Student List
95%

Project Student List

In this lesson, we will create the Student List screen for our Student Management mobile application using React Native, TypeScript, Axios, FlatList, search, and pagination.

The Student List screen will communicate with the PHP REST API, retrieve student records, display them using FlatList, and provide options for searching, editing, viewing, and deleting students.

Project Goal: Build a complete React Native Student List screen connected to the PHP/MySQL REST API using Axios, TypeScript, FlatList, search, pagination, and JWT authentication.

1. Student List Screen Flow

Student List Screen
        ↓
Axios GET Request
        ↓
JWT Authorization
        ↓
PHP Student API
        ↓
MySQL Database
        ↓
JSON Student Data
        ↓
TypeScript
        ↓
FlatList
        ↓
Display Students

2. Why Use FlatList?

React Native FlatList is designed to efficiently display large lists of data.

  • Efficient list rendering.
  • Supports scrolling.
  • Supports pull-to-refresh.
  • Supports infinite loading.
  • Works well with API pagination.
  • Provides item rendering through renderItem.

3. Student Interface

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

This interface represents one student returned by the REST API.

4. Pagination Interface

interface PaginationMeta {
    page: number;
    limit: number;
    total: number;
    total_pages: number;
}

interface StudentResponse {
    success: boolean;
    data: Student[];
    meta: PaginationMeta;
}

5. Import React Native Components

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

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

6. Student List State

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

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

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

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

const [page, setPage] =
    useState(1);

const [hasMore, setHasMore] =
    useState(true);

7. Search State

const [search, setSearch] =
    useState("");

const [searchLoading, setSearchLoading] =
    useState(false);

The search value will be sent to the Student API as a query parameter.

8. Student API Endpoint

GET /api/students.php

The endpoint can return students with pagination and optional search.

/students.php?page=1&limit=10

9. Fetch Students with Axios

const response =
    await api.get<StudentResponse>(
        "/students.php",
        {
            params: {
                page: 1,
                limit: 10
            }
        }
    );

setStudents(
    response.data.data
);

10. Load Students Function

const loadStudents =
    async () => {

    try {

        setLoading(true);

        const response =
            await api.get<StudentResponse>(
                "/students.php",
                {
                    params: {
                        page: 1,
                        limit: 10,
                        search
                    }
                }
            );

        setStudents(
            response.data.data
        );

        setPage(1);

        setHasMore(
            response.data.meta.page
            < response.data.meta.total_pages
        );

    } catch (error) {

        console.log(
            "Unable to load students"
        );

    } finally {

        setLoading(false);

    }
};

11. Load Data When Screen Opens

useEffect(() => {

    loadStudents();

}, []);

The API request runs when the screen is first mounted.

12. Search Input

<TextInput
    placeholder="Search students..."
    value={search}
    onChangeText={setSearch}
/>

The user can enter a name, email, mobile number, or course.

13. Search Students

const searchStudents =
    async (keyword: string) => {

    try {

        setSearchLoading(true);

        const response =
            await api.get<StudentResponse>(
                "/students.php",
                {
                    params: {
                        search: keyword,
                        page: 1,
                        limit: 10
                    }
                }
            );

        setStudents(
            response.data.data
        );

        setPage(1);

        setHasMore(
            response.data.meta.page
            < response.data.meta.total_pages
        );

    } finally {

        setSearchLoading(false);

    }
};

14. Student Card Component

interface StudentCardProps {
    student: Student;
}

const StudentCard =
    ({
        student
    }: StudentCardProps) => {

    return (
        <View>

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

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

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

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

        </View>
    );
};

15. FlatList Basic Structure

<FlatList
    data={students}

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

    renderItem={({ item }) => (
        <StudentCard
            student={item}
        />
    )}
/>

16. KeyExtractor

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

Every student should have a unique key. The database ID is a good choice when it is unique.

17. Student Actions

Each student item can provide actions such as:

  • View profile.
  • Edit student.
  • Delete student.
<TouchableOpacity>
    <Text>View</Text>
</TouchableOpacity>

<TouchableOpacity>
    <Text>Edit</Text>
</TouchableOpacity>

<TouchableOpacity>
    <Text>Delete</Text>
</TouchableOpacity>

18. Delete Student from List

const deleteStudent =
    async (studentId: number) => {

    await api.delete(
        `/students.php?id=${studentId}`
    );

    setStudents(
        previous =>
            previous.filter(
                student =>
                    student.id !== studentId
            )
    );
};

After a successful DELETE request, the local list can immediately remove the deleted student.

19. Load More Students

const loadMore =
    async () => {

    if (
        loadingMore ||
        !hasMore
    ) {
        return;
    }

    const nextPage =
        page + 1;

    try {

        setLoadingMore(true);

        const response =
            await api.get<StudentResponse>(
                "/students.php",
                {
                    params: {
                        search,
                        page: nextPage,
                        limit: 10
                    }
                }
            );

        setStudents(
            previous => [
                ...previous,
                ...response.data.data
            ]
        );

        setPage(nextPage);

        setHasMore(
            nextPage
            < response.data.meta.total_pages
        );

    } finally {

        setLoadingMore(false);

    }
};

20. FlatList Pagination

<FlatList
    data={students}

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

    renderItem={({ item }) => (
        <StudentCard
            student={item}
        />
    )}

    onEndReached={loadMore}

    onEndReachedThreshold={0.5}
/>

When the user reaches the end of the list, another page can be requested.

21. Loading More Indicator

const renderFooter = () => {

    if (!loadingMore) {
        return null;
    }

    return (
        <ActivityIndicator />
    );
};

This indicator can be displayed at the bottom of the list while the next page is loading.

22. Pull to Refresh

const refreshStudents =
    async () => {

    try {

        setRefreshing(true);

        const response =
            await api.get<StudentResponse>(
                "/students.php",
                {
                    params: {
                        search,
                        page: 1,
                        limit: 10
                    }
                }
            );

        setStudents(
            response.data.data
        );

        setPage(1);

        setHasMore(
            response.data.meta.page
            < response.data.meta.total_pages
        );

    } finally {

        setRefreshing(false);

    }
};

23. RefreshControl

<FlatList
    data={students}

    refreshControl={
        <RefreshControl
            refreshing={refreshing}
            onRefresh={
                refreshStudents
            }
        />
    }

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

    renderItem={({ item }) => (
        <StudentCard
            student={item}
        />
    )}
/>

24. Loading and Empty States

{loading &&
    students.length === 0 && (
        <ActivityIndicator />
)}

{!loading &&
    students.length === 0 && (
        <Text>
            No students found
        </Text>
)}

These states provide clear feedback when data is loading or no matching students are available.

25. Error Handling

try {

    const response =
        await api.get<StudentResponse>(
            "/students.php"
        );

    setStudents(
        response.data.data
    );

} catch (error) {

    if (
        axios.isAxiosError(error) &&
        error.response
    ) {

        if (
            error.response.status === 401
        ) {

            // Token expired

        } else {

            // API error

        }

    } else {

        // Network error
    }
}

26. Navigation from Student List

The Student List screen can navigate to other project screens.

Student List
    |
    +---- View → Student Profile
    |
    +---- Edit → Edit Student
    |
    +---- Delete → Delete API
    |
    +---- Add → Add Student

React Navigation can be used to connect these screens.

27. Student List Security

  • Send the JWT with protected API requests.
  • Verify JWT on the server.
  • Do not rely only on mobile UI restrictions.
  • Apply role-based authorization where required.
  • Return only required student fields.
  • Use prepared statements in PHP.
  • Use HTTPS in production.
  • Do not expose passwords or password hashes.

28. Complete Student List Component

const StudentListScreen =
    () => {

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

    const [page, setPage] =
        useState(1);

    const [hasMore, setHasMore] =
        useState(true);

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

    const loadStudents =
        async () => {

        try {

            setLoading(true);

            const response =
                await api.get<StudentResponse>(
                    "/students.php",
                    {
                        params: {
                            page: 1,
                            limit: 10
                        }
                    }
                );

            setStudents(
                response.data.data
            );

            setPage(1);

            setHasMore(
                response.data.meta.page
                < response.data.meta.total_pages
            );

        } catch (error) {

            console.log(error);

        } finally {

            setLoading(false);

        }
    };

    useEffect(() => {

        loadStudents();

    }, []);

    return (

        <View>

            <Text>
                Students
            </Text>

            <FlatList
                data={students}

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

                renderItem={
                    ({ item }) => (
                        <View>

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

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

                        </View>
                    )
                }
            />

        </View>
    );
};

29. Complete Student List Architecture

Student List Screen
        ↓
Search / Refresh / Scroll
        ↓
Axios API Service
        ↓
JWT Interceptor
        ↓
PHP Student API
        ↓
Authentication
        ↓
Authorization
        ↓
MySQL + PDO
        ↓
Paginated JSON
        ↓
TypeScript Interfaces
        ↓
FlatList
        ↓
Student Cards
        ↓
View / Edit / Delete

30. Project Student List Summary

The Student List screen is one of the main screens of our Student Management mobile application.

  • Students are loaded from the PHP REST API.
  • Axios communicates with the backend.
  • JWT protects the API request.
  • TypeScript interfaces provide type safety.
  • FlatList displays the student records efficiently.
  • Search can filter student records.
  • Pagination prevents loading too many records at once.
  • Pull-to-refresh reloads the first page.
  • Load-more functionality retrieves additional pages.
  • View, edit, add, and delete actions can be connected to other screens.
  • The next lesson will create the Student Details screen.

📌 Key Points

  • FlatList is useful for displaying API data in React Native.
  • Use TypeScript interfaces for student data.
  • Axios retrieves students from the REST API.
  • JWT protects authenticated requests.
  • Search can be combined with pagination.
  • FlatList onEndReached can load more records.
  • RefreshControl can provide pull-to-refresh.
  • Loading and empty states improve user experience.
  • Student actions can connect to profile, edit, and delete screens.
  • The backend must enforce authentication and authorization.

🧠 Quick Quiz

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