React Native / Fetch API ба өгөгдөл татах
Fetch API ба өгөгдөл татах
Бодит апп нь серверээс өгөгдөл татдаг — хэрэглэгчийн профайл, курсын жагсаалт, мессеж гэх мэт. React Native-д вэбийн fetch() функц бүрэн ажилладаг тул суулгалт шаардлагагүй. Энэ хичээлд өгөгдөл татах зөв загварыг сурна.
fetch() үндэс
jsx
import { useEffect, useState } from "react";
import {
View,
Text,
FlatList,
ActivityIndicator,
StyleSheet,
} from "react-native";
export default function PostsScreen() {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts?_limit=10")
.then((res) => {
if (!res.ok) throw new Error(`HTTP алдаа: ${res.status}`);
return res.json();
})
.then((data) => setPosts(data))
.catch((err) => setError(err.message))
.finally(() => setLoading(false));
}, []);
if (loading)
return (
<View style={styles.center}>
<ActivityIndicator size="large" color="#22d3ee" />
<Text style={styles.loadingText}>Ачааллаж байна...</Text>
</View>
);
if (error)
return (
<View style={styles.center}>
<Text style={styles.errorText}>⚠ {error}</Text>
</View>
);
return (
<FlatList
data={posts}
keyExtractor={(item) => String(item.id)}
contentContainerStyle={styles.list}
renderItem={({ item }) => (
<View style={styles.card}>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.body} numberOfLines={2}>
{item.body}
</Text>
</View>
)}
/>
);
}
const styles = StyleSheet.create({
center: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#0b1120",
gap: 12,
},
loadingText: { color: "#475569", fontSize: 14 },
errorText: {
color: "#fb7185",
fontSize: 15,
textAlign: "center",
paddingHorizontal: 32,
},
list: { padding: 16, gap: 10, backgroundColor: "#0b1120", flexGrow: 1 },
card: {
backgroundColor: "#0f172a",
padding: 16,
borderRadius: 10,
borderWidth: 1,
borderColor: "#1e293b",
},
title: {
fontSize: 14,
fontWeight: "600",
color: "#f1f5f9",
marginBottom: 6,
textTransform: "capitalize",
},
body: { fontSize: 13, color: "#64748b", lineHeight: 20 },
});
POST, PUT, DELETE хүсэлт илгээх
Зөвхөн унших биш өгөгдөл илгээх, шинэчлэх, устгах хүсэлтүүдийг fetch-н хоёр дахь аргументаар тохируулна:
jsx
// POST — шинэ өгөгдөл үүсгэх
const createPost = async (title, body) => {
const response = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ title, body, userId: 1 }),
});
if (!response.ok) throw new Error("Үүсгэхэд алдаа гарлаа");
const newPost = await response.json();
return newPost;
};
// PUT — бүрэн шинэчлэх
const updatePost = async (id, data) => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts/${id}`,
{
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
},
);
return response.json();
};
// DELETE — устгах
const deletePost = async (id) => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts/${id}`,
{
method: "DELETE",
},
);
return response.ok;
};
Давтан ашиглах fetch hook
Fetch логикийг custom hook болгон тусгаарлах нь дэлгэц бүрт давтан бичихгүй, цэвэр код байлгадаг:
jsx
// hooks/useFetch.js
import { useEffect, useState, useCallback } from "react";
export function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const load = useCallback(async () => {
setLoading(true);
setError(null);
try {
const res = await fetch(url);
if (!res.ok) throw new Error(`Алдаа: ${res.status}`);
const json = await res.json();
setData(json);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}, [url]);
useEffect(() => {
load();
}, [load]);
return { data, loading, error, refetch: load };
}
jsx
// Дэлгэцэд ашиглах нь маш хялбар болно:
import { useFetch } from "../hooks/useFetch";
import {
View,
Text,
ActivityIndicator,
FlatList,
StyleSheet,
} from "react-native";
export default function UsersScreen() {
const {
data: users,
loading,
error,
refetch,
} = useFetch("https://jsonplaceholder.typicode.com/users");
if (loading) return <ActivityIndicator style={{ flex: 1 }} color="#22d3ee" />;
if (error)
return (
<View style={styles.center}>
<Text style={styles.errorText}>{error}</Text>
<Text style={styles.retryBtn} onPress={refetch}>
Дахин оролдох
</Text>
</View>
);
return (
<FlatList
data={users}
keyExtractor={(u) => String(u.id)}
contentContainerStyle={styles.list}
renderItem={({ item }) => (
<View style={styles.row}>
<Text style={styles.name}>{item.name}</Text>
<Text style={styles.email}>{item.email}</Text>
</View>
)}
/>
);
}
const styles = StyleSheet.create({
center: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#0b1120",
gap: 12,
},
errorText: { color: "#fb7185", fontSize: 15 },
retryBtn: { color: "#22d3ee", fontSize: 14, marginTop: 4 },
list: { padding: 16, gap: 8, backgroundColor: "#0b1120", flexGrow: 1 },
row: {
backgroundColor: "#0f172a",
padding: 14,
borderRadius: 10,
borderWidth: 1,
borderColor: "#1e293b",
},
name: { fontSize: 15, fontWeight: "600", color: "#f1f5f9" },
email: { fontSize: 13, color: "#475569", marginTop: 2 },
});
refetch функцийг "Дахин оролдох" товчид холбосноор алдаа гарсан үед хэрэглэгч өөрөө дахин татах боломжтой болно.
Дараагийн хичээлд:
Fetch API-г сурлаа. Дараагийн хичээлд Loading ба error state — ачаалж байгаа үед skeleton харуулах, алдааг хэрэглэгчид ойлгомжтой мэдэгдэх, retry механизм — мэргэжлийн апп-н UX загваруудыг судална.