[React Native] Nesting navigator with stack and tab

Seojin Kwak·2022년 7월 29일

React Navigation

React Native로 앱을 개발하면서 가장 어려움이 많았던 부분은 간단해 보이던 navigator였다.
우선 나는 stack navigator와 tab navigator를 사용할 예정이었기 때문에 모듈을 다운로드했다.

npm add @react-navigation/native
expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
npm add @react-navigation/stack
npm add @react-navigation/bottom-tabs

내가 구성한 navigation을 살펴보면

StackNavigator
	ㄴSignInStack
	ㄴCameraStack
	ㄴAlbumStack
	ㄴMypageStack

TabNavigator
	ㄴCameraStack
	ㄴAlbumStack
	ㄴMypageStack

MainNavigator
	ㄴSignInStack
	ㄴTabNavigator

로그인을 하고 나면 tab navigator 화면으로 넘어가야 하기 때문에, main navigator를 두 가지 스택으로 분리하였다.
각 Tab 별로 stack을 쌓아 tab 속 screen을 관리하였다.

Stack Navigator

import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator();

export function SignInStack() {
    return (
        <Stack.Navigator
            screenOptions = {({ route }) => ({ headerShown: false })}
        >
            <Stack.Screen name = {SignInName} component = {SignInScreen} />
            <Stack.Screen name = {SignUpName} component = {SignUpScreen} />
        </Stack.Navigator>
    )
}

위와 같은 방식으로 다른 Stack들도 구성해주었다.

  • screenoptions: route를 넣어준 이유는, 메소드를 사용해 screen별로 이동하고 route.params로 parameter를 넘겨주기 위해서다.
    그리고 나는 header를 따로 만들었기 때문에 navigation 기본 헤더는 가려주었다.

Tab Navigator

import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { CameraStack, AlbumStack, MypageStack } from './StackNavigator';

const Tab = createBottomTabNavigator();

<NavigationContainer
	independent = {true}
>
	<Tab.Navigator
    	screenOptions = {({ route }) => ({ headerShown: false })}
        initialRouteName = 'AlbumStack'
    >
    	<Tab.Screen name = 'CameraStack' component = {CameraStack} 
        	options = {{
            	tabBarShowLabel: false,
                tabBarIcon: () => (
                	<Image source = {images.camera} />
                ),
                unmountOnBlur: true,
			}} />
		// 나머지 tab screen도 위와 같이 구성
		</Tab.Navigator>
</NavigationContainer>
  • 전체를 navigation container로 감싸주어야 작동한다. nested navigator 구성이기 때문에 independent = {true} 설정도 필요
  • TabNavigator 전체에도 route가 필요했다. 그리고 마찬가디로 header는 가려줌.
  • Tab bar label도 필요 없어서 가려줌.
  • tabBarIcon도 expo vector icon말고 따로 활용하려고 image source 넣어줌
  • unmountOnBlur: 각 tab 이동하고 나면 tab stack history는 없애려고 true로 설정해줬다.

로그인 로직을 분리하여 navigator를 구성하기 위해 파일을 따로 빼서 main navigator를 만들어 stack을 쌓았다.

<NavigationContainer
	independent = {true}
>
	<Stack.Navigator
		screenOptions = {({ route }) => ({ headerShown: false })}
		initialRouteName = {SignInStack}
    >
    {
    	isLogin ? (
        	<>
            <Stack.Screen name = 'TabNavigator' component = {TabNavigator} /> 
            </>   
		) : (
            <>
            <Stack.Screen name = 'SignInStack' component = {SignInStack} />
            <Stack.Screen name = 'TabNavigator' component = {TabNavigator} />
            </>
		)
	}
    </Stack.Navigator>
</NavigationContainer>
profile
Hello, World!

0개의 댓글