React Native / Loading ба error state

Loading ба error state

Аппликейшн өгөгдөл татах үед гурван төлөв байдаг: loading (ачааллаж байна), success (амжилттай), error (алдаа гарлаа). Энэ гурван төлөвийг зөв харуулах нь хэрэглэгчийн туршлагад маш чухал. Хэн ч дэлгэц хоосон харж хүлээхийг дургүйцдэг — loading indicator харуулж байвал апп ажиллаж байгааг мэдэгдэнэ.

Loading, success, error гурван төлөв

useState ашиглан гурван төлөвийг хянана. loading boolean, error string эсвэл null, data татаж авсан өгөгдөл.

jsx
import { useState, useEffect } from "react";
import { View, Text, ActivityIndicator, StyleSheet } from "react-native";

export default function UserProfile() {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/users/1")
      .then((res) => {
        if (!res.ok) throw new Error("Сервер алдаа гарлаа");
        return res.json();
      })
      .then((data) => setUser(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 (
    <View style={styles.container}>
      <Text style={styles.name}>{user.name}</Text>
      <Text style={styles.email}>{user.email}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  center: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#0b1120",
  },
  container: {
    flex: 1,
    padding: 24,
    backgroundColor: "#0b1120",
  },
  loadingText: {
    color: "#94a3b8",
    marginTop: 12,
    fontSize: 14,
  },
  errorText: {
    color: "#fb7185",
    fontSize: 16,
    textAlign: "center",
    paddingHorizontal: 24,
  },
  name: {
    fontSize: 22,
    fontWeight: "bold",
    color: "#f1f5f9",
  },
  email: {
    fontSize: 14,
    color: "#94a3b8",
    marginTop: 6,
  },
});

ActivityIndicator бол React Native-н суурилагдсан loading spinner юм. size="large" томруулна, color өнгийг тохируулна.

ActivityIndicator болон skeleton placeholder

Зарим аппликейшн spinner-н оронд skeleton — агуулгын хэлбэртэй саарал блок — харуулдаг. Энэ нь хэрэглэгчид юу ачаалагдаж байгааг ойлгуулдаг.

jsx
import { View, StyleSheet } from "react-native";

function SkeletonCard() {
  return (
    <View style={styles.card}>
      <View style={styles.skeletonTitle} />
      <View style={styles.skeletonLine} />
      <View style={[styles.skeletonLine, { width: "60%" }]} />
    </View>
  );
}

const styles = StyleSheet.create({
  card: {
    backgroundColor: "#0f172a",
    borderRadius: 12,
    padding: 16,
    marginBottom: 12,
  },
  skeletonTitle: {
    height: 20,
    backgroundColor: "#1e293b",
    borderRadius: 4,
    marginBottom: 12,
    width: "70%",
  },
  skeletonLine: {
    height: 12,
    backgroundColor: "#1e293b",
    borderRadius: 4,
    marginBottom: 8,
    width: "100%",
  },
});

Дахин оролдох (retry) функц

Алдаа гарсан үед хэрэглэгчид дахин оролдох боломж олгоно. retry функц бол loading-г дахин true болгоод fetch дахин ажиллуулдаг хэлбэр.

jsx
import { useState, useCallback } from "react";
import {
  View,
  Text,
  TouchableOpacity,
  ActivityIndicator,
  StyleSheet,
} from "react-native";

export default function RetryExample() {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [data, setData] = useState(null);

  const fetchData = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const res = await fetch("https://jsonplaceholder.typicode.com/posts/1");
      if (!res.ok) throw new Error("Холболт амжилтгүй болсон");
      const json = await res.json();
      setData(json);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  }, []);

  return (
    <View style={styles.container}>
      {loading && <ActivityIndicator color="#22d3ee" />}

      {error && (
        <View style={styles.errorBox}>
          <Text style={styles.errorText}>⚠️ {error}</Text>
          <TouchableOpacity style={styles.retryBtn} onPress={fetchData}>
            <Text style={styles.retryText}>Дахин оролдох</Text>
          </TouchableOpacity>
        </View>
      )}

      {data && !loading && <Text style={styles.title}>{data.title}</Text>}

      {!data && !loading && !error && (
        <TouchableOpacity style={styles.retryBtn} onPress={fetchData}>
          <Text style={styles.retryText}>Өгөгдөл татах</Text>
        </TouchableOpacity>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#0b1120",
    padding: 24,
  },
  errorBox: {
    alignItems: "center",
    gap: 16,
  },
  errorText: {
    color: "#fb7185",
    fontSize: 15,
    textAlign: "center",
  },
  retryBtn: {
    backgroundColor: "#1e293b",
    paddingHorizontal: 20,
    paddingVertical: 10,
    borderRadius: 8,
    borderWidth: 1,
    borderColor: "#22d3ee",
  },
  retryText: {
    color: "#22d3ee",
    fontWeight: "600",
  },
  title: {
    color: "#f1f5f9",
    fontSize: 18,
    textAlign: "center",
  },
});

Энгийн дүрэм: loading үед spinner, error үед retry товч, амжилттай үед өгөгдөл. Энэ гурвыг дагавал таны апп мэргэжлийн харагдана.

Дараагийн хичээлд:

RefreshControl — FlatList дотор доош татах (pull to refresh) функц хэрхэн нэмэх талаар сурна.