[React Native] StackNavigation이 상위인 중첩 네비게이션 구현

RuLu·2024년 12월 8일

React-Native

목록 보기
7/13

완성된 네비게이션 설계 구조

설계 이유

  1. 앱의 확장성을 생각할 때 또 다른 형태의 nav가 언제든지 등장 할 수 있음. 따라서 기능에 따라 네비게이션을 분리한 다음 Main 네비게이션 하위에서 조합하는 것이 유지보수에 이점이 있다고 판단.
  2. 중첩으로 설계한 이유: 구현적 편리함때문에 일기목록을 바텀탭 네비에만 포함하고 DiaryStack 네비에서는 빼려고 함. but 일기목록은 스택안에서 자유롭게 이동되어야 하며, 메인이자 일기 기능이라는 기능상 자연스러움에서도 두 네비게이션 모두에 포함되어야 한다고 생각
  3. 앱 개발은 화면전환이 URL로 매핑되지 않고 네비게이션 코드로 정의됨. 따라서 사용자 친화적 디자인에 중점하여 설계해도 큰 무리가 없음.

타입 선언


export type RouteList = {
/*
DiaryStack과 MainBottomTab모두 최상위 Stack 네비게이션의 하위에 위치한다.
*/
  [ROUTE.DIARY_STACK]: {screen: string; params?: object} | undefined;
  [ROUTE.MAIN_BOTTOM_TAB]: {screen: string; params?: object} | undefined;
  [ROUTE.CALENDER]: undefined;
  [ROUTE.DIARY]: {date: YYYYMMDDHHMM; day: number} | undefined;
  [ROUTE.READ_DIARY]: {id: string} | undefined;
  [ROUTE.WRITE_DIARY]: {date: YYYYMMDDHHMM} | undefined;
  [ROUTE.EDIT_DIARY]: {id: string} | undefined;
};

//최상위 스택 네비에 대한 타입
export type RouteListProps = NativeStackNavigationProp<RouteList>;

//바텀 탭 네비에 대한 타입
export type MainBottomTabRouteProps = BottomTabScreenProps<
  RouteList,
  typeof ROUTE.MAIN_BOTTOM_TAB
>;

export type DiaryStackRouteProps = NativeStackScreenProps<
  RouteList,
  typeof ROUTE.DIARY_STACK
>;

...

최상위 네비게이션 (StackNavigation)

네비게이션 정보를 모두 가지고 있는 최상위 네비게이션. 이외의 네비게이션을 구현해야할 경우 최상위 네비게이션 하위에 적절히 배치하도록 한다.

//App.tsx 최상위 스택 네비 위치
const Stack = createStackNavigator<RouteList>();

function App(): React.JSX.Element {
  ...

  return (
    <SafeAreaView style={{flex: 1}}>
      <NavigationContainer>
        <Stack.Navigator initialRouteName="DiaryStack">
         //상위 네비게이션 연결
          <Stack.Screen name="DiaryStack" component={DiaryStack} />
        </Stack.Navigator>
      </NavigationContainer>
    </SafeAreaView>
  );
}

export default App;

상위 네비게이션 (StackNavigation)

//DiaryStack.tsx 상위네비게이션

const Stack = createStackNavigator<RouteList>();

export default () => {
  return (
    <Stack.Navigator
      initialRouteName="MainBottomTab"
      screenOptions={{headerShown: false, gestureEnabled: true}}>
       // 하위 네비게이션 연결
      <Stack.Screen name="MainBottomTab" component={MainBottomTab} />
      <Stack.Screen name="ReadDiary" component={DiaryReadPage} />
      <Stack.Screen name="WriteDiary" component={DiaryWritePage} />
      <Stack.Screen name="EditDiary" component={DiaryEditPage} />
    </Stack.Navigator>
  );
};

하위 네비게이션 (TabNavigation)

//MainBottomTab.tsx 하위 네비게이션

const Tab = createBottomTabNavigator<RouteList>();

export default () => {
  return (
    <Tab.Navigator>
      <Tab.Screen
        name="Calender"
        component={CalenderPage}
      />
      <Tab.Screen
        name="Diary"
        component={DiaryListPage}
      />
    </Tab.Navigator>
  );
};

서로 다른 종류의 네비게이션 하위에 위치한 페이지끼리의 이동

Tab→ stack의 경우

Tab에 위치한 페이지에서 Stack의 페이지로 이동할때 navigation이 경로를 못잡는 경우가 발생. Tab이 화면상 경로를 아예 바꾸는 것이기 때문.

그래서 이동할 때 아래처럼 작성해야했음

navigation.navigate(ROUTE.MAIN_BOTTOM_TAB, {
          screen: ROUTE.DIARY,
          params: {date: generateYYYYMMDDHHMM(rawDate), day: rawDate.getDay()},
          });

Stack → Tab의 경우

Stack은 경로를 화면에 쌓기 때문에 다른 중첩 네비게이션으로 이동할때 별다를 문제없이 경로를 잡을 수 있음

navigation.navigate(ROUTE.DIARY, {
          date: generateYYYYMMDDHHMM(rawDate),
          day: rawDate.getDay(),
        });
profile
프론트엔드 개발자 루루

0개의 댓글