In this lesson, we will create the Student Details screen for our Student Management mobile application using React Native, TypeScript, Axios, and the PHP REST API.
The screen will receive a student ID, request the student's details from the protected API, and display the complete student profile.
Student List
↓
Select Student
↓
Pass Student ID
↓
Student Details Screen
↓
Axios GET Request
↓
JWT Authentication
↓
PHP REST API
↓
MySQL Database
↓
Student JSON
↓
Display Profile
The Student List should show basic information, while the Details screen can display complete information about one student.
interface Student {
id: number;
name: string;
email: string;
mobile: string;
course: string;
address: string;
}
This interface describes the student object returned by the API.
interface StudentProfileResponse {
success: boolean;
message?: string;
data: Student;
}
The API can return the student inside the data property.
import React, {
useEffect,
useState
} from "react";
import {
View,
Text,
ActivityIndicator,
ScrollView,
TouchableOpacity
} from "react-native";
const [student, setStudent] =
useState<Student | null>(null);
const [loading, setLoading] =
useState(true);
const [error, setError] =
useState("");
The student starts as null because the API data has not
been loaded yet.
React Navigation can pass the student ID from the Student List screen.
const { id } = route.params;
For example, the Details screen may receive:
{
id: 5
}
Our project can use a protected endpoint such as:
GET /api/student_profile.php?id=5
The ID identifies which student should be returned.
const response =
await api.get<StudentProfileResponse>(
"/student_profile.php",
{
params: {
id
}
}
);
setStudent(
response.data.data
);
const loadStudent =
async () => {
try {
setLoading(true);
setError("");
const response =
await api.get<StudentProfileResponse>(
"/student_profile.php",
{
params: {
id
}
}
);
setStudent(
response.data.data
);
} catch (error) {
setError(
"Unable to load student details."
);
} finally {
setLoading(false);
}
};
useEffect(() => {
loadStudent();
}, [id]);
The request runs when the screen opens and whenever the student ID changes.
if (loading) {
return (
<View>
<ActivityIndicator
size="large"
/>
<Text>
Loading student...
</Text>
</View>
);
}
A loading indicator provides feedback while the API request is running.
if (error) {
return (
<View>
<Text>
{error}
</Text>
</View>
);
}
<Text>
{student?.name}
</Text>
Optional chaining prevents an error if the student object is
temporarily null.
<Text>
Name: {student?.name}
</Text>
<Text>
Email: {student?.email}
</Text>
<Text>
Mobile: {student?.mobile}
</Text>
<Text>
Course: {student?.course}
</Text>
<Text>
Address: {student?.address}
</Text>
<ScrollView>
<Text>
Student Profile
</Text>
<Text>
{student?.name}
</Text>
<Text>
{student?.email}
</Text>
<Text>
{student?.mobile}
</Text>
</ScrollView>
ScrollView is useful when the profile contains several fields.
<View>
<Text>
Student Profile
</Text>
<Text>
Name: {student?.name}
</Text>
<Text>
Email: {student?.email}
</Text>
<Text>
Mobile: {student?.mobile}
</Text>
<Text>
Course: {student?.course}
</Text>
<Text>
Address: {student?.address}
</Text>
</View>
From the Student List, navigate to the Details screen and pass the selected student's ID.
navigation.navigate(
"StudentDetails",
{
id: student.id
}
);
The Details screen then uses this ID to request the correct record.
type RootStackParamList = {
StudentList: undefined;
StudentDetails: {
id: number;
};
};
TypeScript can ensure that the Details screen receives a numeric student ID.
catch (error) {
if (
axios.isAxiosError(error) &&
error.response?.status === 401
) {
setError(
"Session expired. Please login again."
);
} else {
setError(
"Unable to load student."
);
}
}
A 401 response usually means that authentication is missing or the token is no longer valid.
if (
axios.isAxiosError(error) &&
error.response?.status === 404
) {
setError(
"Student not found."
);
}
The API should return 404 when the requested student does not exist.
$id = filter_input(
INPUT_GET,
'id',
FILTER_VALIDATE_INT
);
if (!$id) {
http_response_code(400);
echo json_encode([
"success" => false,
"message" => "Invalid student ID"
]);
exit;
}
The API should validate the ID before querying the database.
$stmt = $pdo->prepare(
"SELECT
id,
name,
email,
mobile,
course,
address
FROM students
WHERE id = ?"
);
$stmt->execute([$id]);
$student = $stmt->fetch(
PDO::FETCH_ASSOC
);
A prepared statement protects the database query from SQL injection.
if (!$student) {
http_response_code(404);
echo json_encode([
"success" => false,
"message" => "Student not found"
]);
exit;
}
http_response_code(200);
echo json_encode([
"success" => true,
"data" => $student
]);
const StudentDetailsScreen =
({ route }: any) => {
const { id } = route.params;
const [student, setStudent] =
useState<Student | null>(null);
const [loading, setLoading] =
useState(true);
const [error, setError] =
useState("");
const loadStudent =
async () => {
try {
setLoading(true);
setError("");
const response =
await api.get<StudentProfileResponse>(
"/student_profile.php",
{
params: {
id
}
}
);
setStudent(
response.data.data
);
} catch (error) {
if (
axios.isAxiosError(error) &&
error.response?.status === 404
) {
setError(
"Student not found."
);
} else {
setError(
"Unable to load student."
);
}
} finally {
setLoading(false);
}
};
useEffect(() => {
loadStudent();
}, [id]);
if (loading) {
return (
<View>
<ActivityIndicator
size="large"
/>
<Text>
Loading student...
</Text>
</View>
);
}
if (error) {
return (
<View>
<Text>
{error}
</Text>
</View>
);
}
return (
<ScrollView>
<Text>
Student Details
</Text>
<Text>
ID: {student?.id}
</Text>
<Text>
Name: {student?.name}
</Text>
<Text>
Email: {student?.email}
</Text>
<Text>
Mobile: {student?.mobile}
</Text>
<Text>
Course: {student?.course}
</Text>
<Text>
Address: {student?.address}
</Text>
</ScrollView>
);
};
The Details screen can provide navigation to the Edit Student screen and can also connect to the Delete API.
navigation.navigate(
"EditStudent",
{
id: student.id
}
);
For deletion, the application should first ask the user for confirmation and then call the DELETE API.
Student List
↓
Student ID
↓
React Navigation
↓
Student Details
↓
Axios
↓
JWT Interceptor
↓
PHP API
↓
JWT Verification
↓
PDO + MySQL
↓
Student Record
↓
JSON Response
↓
TypeScript
↓
Student Profile UI
Login
↓
JWT Token
↓
Student List
↓
Select Student
↓
Pass Student ID
↓
Student Details
↓
GET /student_profile.php?id=5
↓
Verify JWT
↓
Validate ID
↓
Query MySQL
↓
Return JSON
↓
Display Student
↓
Edit / Delete
The Student Details screen completes the profile-viewing part of our Student Management application.
Question: Which HTTP method should normally be used to retrieve a student's details from the REST API?