[React Native] Nesting navigator with stack and tab

Seojin Kwak·2022년 7월 29일
0

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개의 댓글