React Native / Stack Navigation

Stack Navigation

Нэгээс олон дэлгэцтэй апп хийхэд navigation хэрэгтэй. Stack Navigation нь дэлгэцүүдийг "овоолон" ажилладаг — шинэ дэлгэц дээр нэмэгдэж, буцах товч дарахад арынх нь харагддаг. Утасны бараг бүх апп ийм загвар ашигладаг.

Суулгалт

React Navigation нь Expo-д суулгалттай ирдэггүй — нэг удаа суулгах шаардлагатай:

bash
npx expo install @react-navigation/native @react-navigation/native-stack
npx expo install react-native-screens react-native-safe-area-context

npx expo install нь npm install-тай ижил боловч Expo-н хувилбартай нийцтэй сангуудыг автоматаар сонгодог тул энэ командыг ашиглах нь зөв.

Үндсэн Stack Navigator тохируулга

jsx
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import HomeScreen from "./screens/HomeScreen";
import DetailScreen from "./screens/DetailScreen";

const Stack = createNativeStackNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator
        initialRouteName="Home"
        screenOptions={{
          headerStyle: { backgroundColor: "#0f172a" },
          headerTintColor: "#f1f5f9",
          headerTitleStyle: { fontWeight: "bold" },
          contentStyle: { backgroundColor: "#0b1120" },
        }}
      >
        <Stack.Screen
          name="Home"
          component={HomeScreen}
          options={{ title: "Нүүр хуудас" }}
        />
        <Stack.Screen
          name="Detail"
          component={DetailScreen}
          options={{ title: "Дэлгэрэнгүй" }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

NavigationContainer нь бүх navigation-г ороосон үндсэн хайрцаг — аппын хамгийн гадна давхарт байх ёстой. Stack.Navigator нь дэлгэцүүдийг удирдана. screenOptions нь бүх дэлгэцэд хэрэглэгдэх нийтлэг тохиргоо.

Дэлгэцүүд хооронд шилжих

navigation prop нь Stack-н бүх дэлгэцт автоматаар дамжигддаг:

jsx
// screens/HomeScreen.jsx
import {
  View,
  Text,
  TouchableOpacity,
  FlatList,
  StyleSheet,
} from "react-native";

const COURSES = [
  { id: "1", slug: "javascript", title: "JavaScript үндэс", color: "#4ade80" },
  { id: "2", slug: "react", title: "React үндэс", color: "#60a5fa" },
  {
    id: "3",
    slug: "react-native",
    title: "React Native үндэс",
    color: "#22d3ee",
  },
];

export default function HomeScreen({ navigation }) {
  return (
    <FlatList
      data={COURSES}
      keyExtractor={(item) => item.id}
      contentContainerStyle={styles.list}
      renderItem={({ item }) => (
        <TouchableOpacity
          style={styles.card}
          onPress={() => navigation.navigate("Detail", { course: item })}
        >
          <View style={[styles.dot, { backgroundColor: item.color }]} />
          <Text style={styles.title}>{item.title}</Text>
          <Text style={styles.arrow}></Text>
        </TouchableOpacity>
      )}
    />
  );
}

const styles = StyleSheet.create({
  list: { padding: 16, gap: 10 },
  card: {
    flexDirection: "row",
    alignItems: "center",
    backgroundColor: "#0f172a",
    padding: 16,
    borderRadius: 10,
    borderWidth: 1,
    borderColor: "#1e293b",
    gap: 12,
  },
  dot: { width: 10, height: 10, borderRadius: 5 },
  title: { flex: 1, fontSize: 15, color: "#f1f5f9" },
  arrow: { fontSize: 20, color: "#475569" },
});

navigation.navigate('Detail', { course: item }) — хоёр дахь аргументт өгөгдөл дамжуулж болно. Энэ нь дараагийн дэлгэцт route.params -аар хүрэлцдэг.

route.params-аар өгөгдөл хүлээн авах

jsx
// screens/DetailScreen.jsx
import { View, Text, TouchableOpacity, StyleSheet } from "react-native";

export default function DetailScreen({ route, navigation }) {
  const { course } = route.params;

  return (
    <View style={styles.container}>
      <View style={[styles.badge, { borderColor: course.color }]}>
        <Text style={[styles.badgeText, { color: course.color }]}>
          {course.slug}
        </Text>
      </View>

      <Text style={styles.title}>{course.title}</Text>
      <Text style={styles.description}>
        Энэ курсийн тухай дэлгэрэнгүй мэдээлэл энд байна.
      </Text>

      <TouchableOpacity
        style={styles.button}
        onPress={() => navigation.goBack()}
      >
        <Text style={styles.buttonText}>← Буцах</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 24,
    backgroundColor: "#0b1120",
  },
  badge: {
    alignSelf: "flex-start",
    borderWidth: 1,
    borderRadius: 6,
    paddingHorizontal: 10,
    paddingVertical: 4,
    marginBottom: 16,
  },
  badgeText: { fontSize: 13, fontWeight: "600" },
  title: {
    fontSize: 24,
    fontWeight: "bold",
    color: "#f1f5f9",
    marginBottom: 12,
  },
  description: {
    fontSize: 15,
    color: "#94a3b8",
    lineHeight: 24,
    marginBottom: 32,
  },
  button: {
    backgroundColor: "#0f172a",
    padding: 14,
    borderRadius: 10,
    alignItems: "center",
    borderWidth: 1,
    borderColor: "#1e293b",
  },
  buttonText: { color: "#94a3b8", fontSize: 15 },
});

navigation.goBack() нь өмнөх дэлгэц рүү буцдаг — header дахь буцах товчтой ижил үйлдэл хийдэг.

jsx
// Дэлгэц рүү шилжих (параметртэй эсвэл параметргүй)
navigation.navigate("ScreenName");
navigation.navigate("ScreenName", { id: 123 });

// Буцах
navigation.goBack();

// Stack-ийг цэвэрлэж тодорхой дэлгэц рүү шилжих
navigation.reset({ index: 0, routes: [{ name: "Home" }] });

// Дэлгэцийн гарчгийг програмаар солих
navigation.setOptions({ title: "Шинэ гарчиг" });

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

Stack Navigation-г тохируулж, дэлгэцүүд хооронд шилжиж сурлаа. Дараагийн хичээлд Tab Navigation — дэлгэцийн доод хэсэгт байдаг tab bar хийнэ. Instagram, YouTube зэрэг аппын доод цэстэй яг адилхан.