React Native / RefreshControl (pull to refresh)

RefreshControl (pull to refresh)

Орчин үеийн мобайл апп бүхэнд байдаг нэг functionality бол pull to refresh — жагсаалтыг доош татахад дахин шинэчлэгддэг. Instagram, Twitter, Gmail бүгд ингэж ажилладаг. React Native-д RefreshControl component ашиглан энэ функцийг хялбархан нэмж болно.

RefreshControl үндэс

RefreshControl-ийг ScrollView эсвэл FlatListrefreshControl prop-д дамжуулна. refreshing boolean төлөв, onRefresh callback шаардлагатай.

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

const INITIAL_DATA = [
  { id: "1", title: "React Native суулгалаа" },
  { id: "2", title: "Expo ажиллуулсан" },
  { id: "3", title: "Анхны апп бичсэн" },
];

export default function RefreshExample() {
  const [data, setData] = useState(INITIAL_DATA);
  const [refreshing, setRefreshing] = useState(false);

  const onRefresh = useCallback(async () => {
    setRefreshing(true);
    // Серверээс шинэ өгөгдөл татах
    await new Promise((resolve) => setTimeout(resolve, 1500));
    setData((prev) => [
      { id: Date.now().toString(), title: "Шинэ мэдэгдэл ирлээ 🎉" },
      ...prev,
    ]);
    setRefreshing(false);
  }, []);

  return (
    <FlatList
      data={data}
      keyExtractor={(item) => item.id}
      renderItem={({ item }) => (
        <View style={styles.item}>
          <Text style={styles.itemText}>{item.title}</Text>
        </View>
      )}
      refreshControl={
        <RefreshControl
          refreshing={refreshing}
          onRefresh={onRefresh}
          tintColor="#22d3ee"
          colors={["#22d3ee"]}
        />
      }
      contentContainerStyle={styles.list}
    />
  );
}

const styles = StyleSheet.create({
  list: {
    backgroundColor: "#0b1120",
    padding: 16,
  },
  item: {
    backgroundColor: "#0f172a",
    padding: 16,
    borderRadius: 10,
    marginBottom: 10,
    borderWidth: 1,
    borderColor: "#1e293b",
  },
  itemText: {
    color: "#f1f5f9",
    fontSize: 15,
  },
});

tintColor нь iOS дээрх spinner-н өнгийг тохируулна. colors prop нь Android дээр хэрэглэгдэнэ. Хоёуланг нь зааж өгвөл хоёр платформд зөв харагдана.

API-с өгөгдөл татаж refresh хийх

Жинхэнэ апп дахь хэрэглээ — серверээс шинэ мэдэгдэл татах:

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

export default function PostsFeed() {
  const [posts, setPosts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);

  const fetchPosts = async () => {
    const res = await fetch(
      "https://jsonplaceholder.typicode.com/posts?_limit=10",
    );
    return res.json();
  };

  useEffect(() => {
    fetchPosts()
      .then(setPosts)
      .finally(() => setLoading(false));
  }, []);

  const onRefresh = useCallback(async () => {
    setRefreshing(true);
    try {
      const fresh = await fetchPosts();
      setPosts(fresh);
    } finally {
      setRefreshing(false);
    }
  }, []);

  if (loading) {
    return (
      <View style={styles.center}>
        <ActivityIndicator size="large" color="#22d3ee" />
      </View>
    );
  }

  return (
    <FlatList
      data={posts}
      keyExtractor={(item) => item.id.toString()}
      renderItem={({ item }) => (
        <View style={styles.card}>
          <Text style={styles.cardTitle}>{item.title}</Text>
          <Text style={styles.cardBody} numberOfLines={2}>
            {item.body}
          </Text>
        </View>
      )}
      refreshControl={
        <RefreshControl
          refreshing={refreshing}
          onRefresh={onRefresh}
          tintColor="#22d3ee"
          colors={["#22d3ee"]}
        />
      }
      contentContainerStyle={styles.list}
    />
  );
}

const styles = StyleSheet.create({
  center: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#0b1120",
  },
  list: {
    padding: 16,
    backgroundColor: "#0b1120",
  },
  card: {
    backgroundColor: "#0f172a",
    borderRadius: 12,
    padding: 16,
    marginBottom: 12,
    borderWidth: 1,
    borderColor: "#1e293b",
  },
  cardTitle: {
    color: "#f1f5f9",
    fontSize: 15,
    fontWeight: "600",
    marginBottom: 6,
  },
  cardBody: {
    color: "#94a3b8",
    fontSize: 13,
    lineHeight: 18,
  },
});

ScrollView дахь RefreshControl

FlatList биш ScrollView ашиглаж байгаа бол яг адилхан аргаар нэмнэ:

jsx
import { ScrollView, RefreshControl, Text, StyleSheet } from "react-native";

export default function ScrollableScreen({ content }) {
  const [refreshing, setRefreshing] = useState(false);

  const onRefresh = async () => {
    setRefreshing(true);
    await loadNewContent();
    setRefreshing(false);
  };

  return (
    <ScrollView
      refreshControl={
        <RefreshControl
          refreshing={refreshing}
          onRefresh={onRefresh}
          tintColor="#22d3ee"
          colors={["#22d3ee"]}
        />
      }
      style={styles.scroll}
    >
      <Text style={styles.text}>{content}</Text>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  scroll: {
    flex: 1,
    backgroundColor: "#0b1120",
  },
  text: {
    color: "#94a3b8",
    padding: 20,
    lineHeight: 24,
  },
});

Pull to refresh нэмэхэд ердөө 5 мөр код хэрэгтэй. refreshing state, onRefresh функц, RefreshControl component — энэ гуравтай апп нь орчин үеийн мобайл туршлагатай болно.

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

Infinite Scroll — хэрэглэгч жагсаалтын эцэст хүрэх үед автоматаар дараагийн хуудсыг татах функц сурна.