본문 바로가기
React Native/네비게이션

react navigation 배우기 5부 - 네스팅 네비게이터

by 붕어사랑 티스토리 2023. 2. 13.
반응형

1. 네스팅 네비게이터란

아래와 같이 네비게이터 안에있는 스크린이 네비게이터를 품고 있으면 이를 네스팅 네비게이터라고 합니다.

 

function Home() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Feed" component={Feed} />
      <Tab.Screen name="Messages" component={Messages} />
    </Tab.Navigator>
  );
}

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="Home"
          component={Home}
          options={{ headerShown: false }}
        />
        <Stack.Screen name="Profile" component={Profile} />
        <Stack.Screen name="Settings" component={Settings} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

 

위 코드의 구조는 아래와 같이 됩니다

 

Stack.Navigator

    □ Home (Tab.Navigator)
        * Feed (Screen)
         Messages (Screen)
     Profile (Screen)
     Settings (Screen)

 

 

보시는바와 같이 Home 스크린은 스크린이자 네비게이터 역할을 하고 있습니다.

 

 

 

2. 네스팅 네비게이터의 특징

  • 각각의 네비게이터는 독립된 히스토리 스택을 가집니다
  • 각각의 네비게이터는 독립된 option값을 가집니다
  • 네비게이터 안에 있는 각각의 스크린은 그들의 params을 가지게 됩니다.

 

 

3. 네비게이터 액션의 버블링


현재 네비게이터에서 발생한 action을 핸들링 할 수 없으면, 이 액션은 버블링됩니다

 

 

만약 자식 네비게이터의 첫번째 스크린에서 goBack()을 호출할경우 더이상 back할 스크린이 없으므로 부모의 네비게이터에서 goBack()을 이어받습니다

 

다른 navigate 메소드 또한 마찬가지입니다. 만약 위 예제에서 Feed 스크린에서 navigate("Settings")를 호출하면, 자식 네비게이터에서는 Setting 스크린이 없으므로 부모의 네비게이터가 이를 이어받아 세팅 스크린으로 이동하도록 처리합니다.

 

 

 

4. 네비게이터 specific method의 사용

네스팅된 네비게이터는 부모의 네비게이터 specific method를 사용가능합니다.

사용법은 navigation 프로퍼티를 이용하면 됩니다.

 

가령 예를들어 drawer navigator 안에 stack navigator가 있을 경우, stack navigator 안에 스크린은 openDrawer, closeDrawer, toggleDrawer 같은 메소드를 사용할 수 있습니다.

 

비슷한 예시로 stack navigator 안에 tab navigator가 있을 경우, tab navigator의 스크린은 push나 replace 같은 메소드를 사용할 수 있습니다.

 

부모의 네비게이터에 자식의 네비게이터에 액션을 전달하는 방법은 다음과 같이 dispatch를 이용합니다

 

navigation.dispatch(DrawerActions.toggleDrawer());

 

 

 

 

5. 부모의 네비게이터 이벤트를 받는법

기본적으로 부모의 네비게이터 이벤트는 자식의 네비게이터에 전달되지 않습니다.

부모의 네비게이터 이벤트를 받으려면 아래처럼 getParent를 사용하여 명시적으로 이벤트 리스너를 지정해줍니다.

 

const unsubscribe = navigation
  .getParent('MyTabs')
  .addListener('tabPress', (e) => {
    // Do something
  });

 

 

 

6. ui 렌더링시 주의사항

부모의 네비게이터 ui는 자식의 네비게이터 ui 위에 렌더링됩니다

 

예를들어 스택 네비게이터 안에 드로어 네비게이터가 있을경우, drawer는 스택네비게이터의 header 밑으로 나타나게 됩니다.

 

이는 몹시 중요한 사항이며, 네비게이터를 네스팅 할 때 반드시 고려해야될 사항입니다.

아래는 ui설계시 숙지해야 할 대표적인 사항입니다.

  • 탭 네비게이터를 스택 네비게이터의 자식으로 네스팅하면, 새로운 스크린에 스택에 쌓일 때 탭바를 가립니다
  • 드로어 네비게이터를 스택 네비게이터의 자식으로 네스팅하면, header를 가리지 않는 이상 drawer는 헤더에 가려집니다
  • 스택 네비게이터가 드로어 네비게이터의 자식이 될 경우, drawer는 항상 헤더 위로 나타납니다
  • 스택 네비게이터가 탭 네비게이터의 자식이 될 경우, 탭바는 항상 보이게 됩니다

 

 

일반적으로 네스팅을 할 경우, 부모의 헤더보다, 자식의 헤더를 우선순위로 정하고 아래처럼 부모의 헤더를 가리는게 좋습니다(headerShown : false)

여러개의 네비게이터가 중첩되도 이 원리는 마찬가지입니다. 가장 아래있는 자식의 헤더만 보여주는것이 좋습니다.

function Home() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Profile" component={Profile} />
      <Tab.Screen name="Settings" component={Settings} />
    </Tab.Navigator>
  );
}

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="Home"
          component={Home}
          options={{ headerShown: false }}
        />
        <Stack.Screen name="EditPost" component={EditPost} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

 

 

 

 

7. 네비게이터의 initialRoute 설정

기본적으로 nested 된 네비게이터의 특정 스크린으로 navigate 할 때, 그 스크린이 inital 스크린으로 사용되며, nested된 네비게이터의 initialRouteName 프로퍼티는 무시됩니다.

 

이 행동을 disable 하려면 initail 값을 false로 주면 됩니다. 이렇게하면 initialRoute의 스크린까지 렌더링 합니다.

navigation.navigate('Root', {
  screen: 'Settings',
  initial: false,
});

Setting 스크린에서 백버튼을 누를시, Root의 initial 스크린으로 이동하게 됩니다.

 

 

 

반응형

댓글