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 загваруудыг судална.