React Native / Nested Navigation

Nested Navigation

Бодит аппуудад navigation нь нэг давхар байдаггүй. Instagram-д доод tab bar байхын зэрэгцээ нэг tab дотроо Stack navigator ажилладаг — профайл дарахад дэлгэц давхарлагддаг, буцах товч харагддаг. Энэ загварыг Nested Navigation гэдэг.

Яагаад nested navigation хэрэгтэй вэ?

Жишээлбэл, доод tab-тай апп бай. "Сургалтууд" табыг дарахад курсын жагсаалт гардаг. Жагсаалтаас курс дарахад дэлгэрэнгүй хуудас нээгддэг — гэхдээ доод tab bar хэвээр харагдаж байх ёстой. Үүнийг хийхийн тулд Tab дотор Stack шигтгэнэ:

код
NavigationContainer
  └── BottomTabNavigator          ← гадна tab
        ├── HomeScreen
        ├── CoursesStack          ← tab дотор stack
        │     ├── CourseListScreen
        │     └── CourseDetailScreen
        └── ProfileScreen

Tab дотор Stack шигтгэх

jsx
import { NavigationContainer } from "@react-navigation/native";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { Ionicons } from "@expo/vector-icons";
import HomeScreen from "./screens/HomeScreen";
import CourseListScreen from "./screens/CourseListScreen";
import CourseDetailScreen from "./screens/CourseDetailScreen";
import ProfileScreen from "./screens/ProfileScreen";

const Tab = createBottomTabNavigator();
const CoursesStack = createNativeStackNavigator();

// Сургалтууд tab-н дотоод Stack
function CoursesNavigator() {
  return (
    <CoursesStack.Navigator
      screenOptions={{
        headerStyle: { backgroundColor: "#0f172a" },
        headerTintColor: "#f1f5f9",
        contentStyle: { backgroundColor: "#0b1120" },
      }}
    >
      <CoursesStack.Screen
        name="CourseList"
        component={CourseListScreen}
        options={{ title: "Сургалтууд" }}
      />
      <CoursesStack.Screen
        name="CourseDetail"
        component={CourseDetailScreen}
        options={{ title: "Дэлгэрэнгүй" }}
      />
    </CoursesStack.Navigator>
  );
}

// Үндсэн Tab Navigator
export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator
        screenOptions={({ route }) => ({
          headerShown: false, // Stack-н өөрийн header-г ашиглана
          tabBarStyle: {
            backgroundColor: "#0f172a",
            borderTopColor: "#1e293b",
          },
          tabBarActiveTintColor: "#22d3ee",
          tabBarInactiveTintColor: "#475569",
        })}
      >
        <Tab.Screen
          name="Home"
          component={HomeScreen}
          options={{
            title: "Нүүр",
            tabBarIcon: ({ focused, color, size }) => (
              <Ionicons
                name={focused ? "home" : "home-outline"}
                size={size}
                color={color}
              />
            ),
          }}
        />
        <Tab.Screen
          name="Courses"
          component={CoursesNavigator} // ← Stack-г Tab дотор оруулав
          options={{
            title: "Сургалтууд",
            tabBarIcon: ({ focused, color, size }) => (
              <Ionicons
                name={focused ? "book" : "book-outline"}
                size={size}
                color={color}
              />
            ),
          }}
        />
        <Tab.Screen
          name="Profile"
          component={ProfileScreen}
          options={{
            title: "Профайл",
            tabBarIcon: ({ focused, color, size }) => (
              <Ionicons
                name={focused ? "person" : "person-outline"}
                size={size}
                color={color}
              />
            ),
          }}
        />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

headerShown: false нь Tab Navigator-н header-г нуудаг — ингэснээр Stack-н дотоод header давхардахгүй.

Nested navigator дотроос гадагш navigate хийх

Stack дотроос өөр tab руу шилжихийг хүсвэл navigation.navigatetab-н нэр-ийг дамжуулна:

jsx
// CoursesStack дотроос Profile tab руу шилжих
navigation.navigate("Profile");

// Тодорхой screen-ийг нэрлэх
navigation.navigate("Courses", {
  screen: "CourseDetail",
  params: { slug: "javascript" },
});

Гурван давхар nested: Drawer → Tab → Stack

Том аппуудад гурван navigator хавчуулдаг нь бий:

jsx
// Drawer → Tab → Stack загвар
function MainTabs() {
  return (
    <Tab.Navigator screenOptions={{ headerShown: false }}>
      <Tab.Screen name="HomeTab" component={HomeStack} />
      <Tab.Screen name="CoursesTab" component={CoursesStack} />
    </Tab.Navigator>
  );
}

export default function App() {
  return (
    <NavigationContainer>
      <Drawer.Navigator screenOptions={{ headerShown: false }}>
        <Drawer.Screen name="Main" component={MainTabs} />
        <Drawer.Screen name="Settings" component={SettingsScreen} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}

Давхарлалт хэдэн ч байж болно — гол зарчим нь хүүхэд navigator-ийн component prop-д эцэг navigator-г дамжуулах явдал.

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

Nested navigation-г ойлголоо — энэ нь жинхэнэ апп бүтээхэд хамгийн их ашиглагддаг загваруудын нэг. Дараагийн хичээлд Navigation параметр дамжуулах — дэлгэцүүд хооронд өгөгдөл дамжуулах бүх арга замыг дэлгэрэнгүй судална.