Search

React Native에서 Navigation 톺아보기

Tags
React Native
작성일

1. 개요

React Native Expo에서 Navigation에 대해 조금 더 깊게 알아보겠습니다.

2. 환경 설정

React 에서는 React Router DOM 라이브러리를 활용하여 화면을 전환했다면, React Native 에서는 React Navigation 라이브러리를 사용합니다.
패키지 설치는 다음 명령어를 입력합니다.
$ npm install @react-navigation/native
Shell
복사
추가적으로 Dependency를 설정해줍니다.
$ npx expo install react-native-screens react-native-safe-area-context
Shell
복사

3. Navigation의 종류

3-1. Stack Navigator

화면 전환을 스택 구조로 관리합니다. 새로운 화면을 추가하면 스택에 쌓이고 뒤로 가기를 하면 스택에서 제거됩니다. 자연스러운 사용자 경험을 제공합니다.
$ npm install @react-navigation/stack
Shell
복사
기본적인 예제 코드는 다음과 같습니다.
import { createStackNavigator } from '@react-navigation/stack'; const Stack = createStackNavigator(); function MyStack() { return ( <Stack.Navigator> <Stack.Screen name="Home" component={HomeScreen} /> <Stack.Screen name="Details" component={DetailsScreen} /> </Stack.Navigator> ); }
JavaScript
복사

3-2. Tab Navigator

탭 네비게이터는 화면 하단이나 상단에 탭을 배치하여 화면 간에 전환할 수 있도록 합니다. 일반적으로 앱의 주요 섹션을 탐색하는 데 사용됩니다
$ npm install @react-navigation/bottom-tabs
Shell
복사
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; const Tab = createBottomTabNavigator(); function MyTabs() { return ( <Tab.Navigator> <Tab.Screen name="Home" component={HomeScreen} /> <Tab.Screen name="Settings" component={SettingsScreen} /> </Tab.Navigator> ); }
JavaScript
복사
이쯤 되면 규칙이 보이시나요? createXXXNavigator를 만들고, 각 Screen은 Navigator로 감싸줍니다. Navigator와 Screen에 대한 자세한 내용은 다음 챕터에서 설명하겠습니다.

3-3. Drawer Navigator

4. Navigation Container와 Navigator

Navigation을 사용하고자 할 때는 App을 <NavigationContainer로 감싸주어야 합니다.
그리고 안에 각 종 Navigator (ex) Tab.Navigator, Drawer.Navigator, Stack.Navigator)를 사용합니다.
 이 때 Navigator은 어떤 역할을 하는 걸까요?
Navigator는 페이지 간의 전환을 관리하는 컴포넌트 입니다. 우리는 중첩된 Navigator를 통해 앱의 복잡한 화면 전환을 관리할 수 있습니다.
예를 들어, 메인 화면의 탭에는 홈과 마이페이지가 있다고 가정해보겠습니다. 그리고 홈 페이지에서는 유저의 피드를 자세히 보거나, 자신의 피드를 올릴 수 있습니다.
여기서 두 개의 네비게이터가 존재하는데, 첫 번째는 <Tab.Navigator>로 Home과 Mypage를 가지고 있습니다. 두 번째는 <Stack.Navigator> 로 마찬가지로 Home과 UserDetailFeed, UploadFeed 등이 있을 수 있습니다. (이름은 신경쓰지 않아도 됩니다)
참고로 Tab의 Home과 Stack의 Home은 다릅니다. Tab의 Home은 <Stack.Container>를 가르키고 Stack의 Home은 <Stack.Screen>를 가르킵니다.
대략적인 코드는 다음과 같을 수 있습니다.
const Stack = createStackNavigator(); const Tab = createBottomTabNavigator(); function HomeStack() { return ( <Stack.Navigator> <Stack.Screen name="Home" component={HomeScreen} /> <Stack.Screen name="UserDetailFeed" component={UserDetailFeedScreen} /> <Stack.Screen name="UploadFeed" component={UploadFeedScreen} /> </Stack.Navigator> ); } export default function App() { return ( <NavigationContainer> <Tab.Navigator> <Tab.Screen name="Home" component={HomeStack} /> <Tab.Screen name="Mypage" component={MypageScreen} /> </Tab.Navigator> </NavigationContainer> ); }
TypeScript
복사

5. Type Checking with Type Script

Navigation을 사용할 때 타입 체크는 필요합니다.
먼저 타입 체크를 통해 각 화면에 전달되는 파라미터의 타입을 명확하게 정의할 수 있습니다. 예를 들어, 특정 화면이 특정 타입의 파라미터를 요구할 때, 잘못된 타입의 파라미터를 전달하는 오류를 사전에 방지할 수 있습니다.
예를 들어, Profile 화면에 userId: string 파라미터가 필요하다면, 타입 체크를 통해 numberboolean 등 다른 타입의 값을 실수로 전달하는 것을 방지할 수 있습니다.
위 예제를 Type Checking 해보겠습니다.
type HomeStackParamList = { Home: undefined; // Home 화면은 파라미터가 없습니다. UserDetailFeed: { userId: string }; // UserDetailFeed 화면은 userId 파라미터를 필요로 합니다. UploadFeed: undefined; // UploadFeed 화면은 파라미터가 없습니다. };
TypeScript
복사
참고로 undefined은 해당 route에 파라미터가 없다는 것을 의미합니다.
매핑을 정의했다면 우리는 Navigator 컴포넌트에 그것을 사용할 수 있도록 해주어야 합니다. 관련된 코드를 하나의 묶음으로 정의한다면 다음과 같습니다.
type HomeStackParamList = { Home: undefined; // Home 화면은 파라미터가 없습니다. UserDetailFeed: { userId: string }; // UserDetailFeed 화면은 userId 파라미터를 필요로 합니다. UploadFeed: undefined; // UploadFeed 화면은 파라미터가 없습니다. }; const Stack = createStackNavigator<HomeStackParamList>(); function HomeStack() { return ( <Stack.Navigator> <Stack.Screen name="Home" component={HomeScreen} /> <Stack.Screen name="UserDetailFeed" component={UserDetailFeedScreen} /> <Stack.Screen name="UploadFeed" component={UploadFeedScreen} /> </Stack.Navigator> ); }
TypeScript
복사

5-1. 중첩 Navigator Type Checking

Tab.Navigator에는 Stack.Navigator가 중첩되어 있습니다. TypeChecking 할 때도 이를 명시해줄 수 있습니다.
type TabParamList = { Home: NavigatorScreenParams<HomeStackParamList>; // Home 탭은 HomeStack을 가리킵니다. Mypage: undefined; // Mypage 화면은 파라미터가 없습니다. };
TypeScript
복사

5-2. Screen에서 사용

import { NativeStackScreenProps } from '@react-navigation/native-stack'; type Props = NativeStackScreenProps<HomeStackParamList, 'UserDetailFeed'>; function UserDetailFeedScreen({ route, navigation }: Props) { // route.params.userId로 userId 접근 가능 return ( // JSX 코드 ); }
TypeScript
복사

Reference