노현진's Blog

React Navigation 설정 방법

React Native 프로젝트에서 React Navigation 설정 방법에 대해 정리한 페이지입니다.

Posted
Preview Image
By HyunJinNo

Tags

Mobile, React Native, React Navigation, TypeScript

Environment

OS: Windows 11

@react-navigation/native v7.1.9

@react-navigation/native-stack v7.3.13

react v19.0.0

react-native v0.79.2

react-native-safe-area-context v5.4.1

react-native-screens v4.11.0

1. 개요

React Native 프로젝트에서 React Navigation 설정 방법에 대해 정리한 페이지입니다. React Native CLI로 프로젝트를 생성하였으며 Android 플랫폼을 기준으로 설명합니다.

2. Step 1 - 패키지 설치하기

먼저 다음 명령어를 입력하여 React Navigation 관련 패키지들을 설치합니다.

bash
1npm install @react-navigation/native react-native-screens react-native-safe-area-context

3. Step 2 - MainActivity.kt 설정하기

android/app/src/main/java/[프로젝트 명]/MainActivity.kt 파일을 열고 다음 코드를 추가합니다.

kotlin
1import android.os.Bundle
kotlin
1override fun onCreate(savedInstanceState: Bundle?) {
2  super.onCreate(null)
3}

즉, 다음과 같이 작성되어야 합니다.

kotlin
1package com.example
2
3import android.os.Bundle
4import com.facebook.react.ReactActivity
5import com.facebook.react.ReactActivityDelegate
6import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
7import com.facebook.react.defaults.DefaultReactActivityDelegate
8
9class MainActivity : ReactActivity() {
10
11  /**
12   * Returns the name of the main component registered from JavaScript. This is used to schedule
13   * rendering of the component.
14   */
15  override fun getMainComponentName(): String = "example"
16
17  /**
18   * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
19   * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
20   */
21  override fun createReactActivityDelegate(): ReactActivityDelegate =
22    DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
23
24  override fun onCreate(savedInstanceState: Bundle?) {
25    super.onCreate(null)
26  }
27}

4. Step 3 - @react-navigation/native-stack 패키지 설치하기

다음 명렁어를 입력하여 @react-navigation/native-stack 패키지를 설치합니다.

bash
1npm install @react-navigation/native-stack

5. Step 4 - 타입 정의하기

React Navigation을 TypeScript로 사용할 때, 안전한 내비게이션과 라우팅을 위해 타입을 정의해야 합니다.

typescript
1import { RouteProp } from "@react-navigation/native";
2import { NativeStackNavigationProp } from "@react-navigation/native-stack";
3
4export type RootStackParamList = {
5  Home: undefined;
6  Setting: undefined;
7};
8
9declare global {
10  namespace ReactNavigation {
11    interface RootParamList extends RootStackParamList {}
12  }
13
14  interface RootStackScreenProps<T extends keyof RootStackParamList> {
15    navigation: NativeStackNavigationProp<RootStackParamList, T>;
16    route: RouteProp<RootStackParamList, T>;
17  }
18}

위의 코드를 설명하자면 다음과 같습니다.

5.1. 스택 내비게이션의 화면 목록 정의

typescript
1export type RootStackParamList = {
2  Home: undefined;
3  Setting: undefined;
4};

RootStackParamList는 스택 내비게이션에 포함된 화면들을 정의한 타입입니다. 위의 코드에서는 HomeSetting이라는 두 개의 화면이 존재하며, 둘 다 매개변수를 받지 않기 때문에 undefined로 설정되어 있습니다. 만약 어떤 화면이 매개변수를 받는다면, Profile: { userId: string }과 같이 명시하면 됩니다.

5.2. 전역 타입 확장

typescript
1declare global {
2  namespace ReactNavigation {
3    interface RootParamList extends RootStackParamList {}
4  }
5}

ReactNavigation.RootParamList를 확장하여 RootStackParamList와 연결합니다. 이렇게 하면 useNavigation 같은 훅을 사용할 때 자동으로 타입을 인식할 수 있습니다.

5.3. 화면 컴포넌트용 Props 타입

typescript
1declare global {
2  interface RootStackScreenProps<T extends keyof RootStackParamList> {
3    navigation: NativeStackNavigationProp<RootStackParamList, T>;
4    route: RouteProp<RootStackParamList, T>;
5  }
6}

스택 내비게이션의 각 화면 컴포넌트의 props 타입을 정의할 때 사용할 인터페이스를 선언합니다. 선언 전에는 다음과 같이 props 타입을 지정해야 합니다.

typescript
1import { NativeStackScreenProps } from "@react-navigation/native-stack";
2import { RootStackParamList } from "@src/app/routes/navigationTypes";
3import { DiaryUpdateEditor } from "@src/widgets/diaryUpdateEditor";
4import React from "react";
5
6export const DiaryUpdateScreen = ({
7  route,
8}: NativeStackScreenProps<RootStackParamList, "DiaryUpdate">) => {
9  return <DiaryUpdateEditor diary={route.params.diary} />;
10};

반면에, RootStackScreenProps 타입을 사용하면 다음과 같이 props 타입을 지정할 수 있습니다.

typescript
1import { DiaryUpdateEditor } from "@src/widgets/diaryUpdateEditor";
2import React from "react";
3
4export const DiaryUpdateScreen = ({
5  route,
6}: RootStackScreenProps<"DiaryUpdate">) => {
7  return <DiaryUpdateEditor diary={route.params.diary} />;
8};

6. Step 5 - 화면 컴포넌트 생성하기

다음과 같이 간단한 화면 컴포넌트를 정의합니다.

typescript
1import { useNavigation } from "@react-navigation/native";
2import { Button, Text, View } from "react-native";
3
4export const HomeScreen = () => {
5  const navigation = useNavigation();
6
7  return (
8    <View>
9      <Text>Home</Text>
10      <Button
11        title="설정화면으로"
12        onPress={() => navigation.navigate("Setting")}
13      />
14    </View>
15  );
16};
typescript
1import { Text, View } from "react-native";
2
3export const SettingScreen = () => {
4  return (
5    <View>
6      <Text>Setting</Text>
7    </View>
8  );
9};

7. Step 6 - 내비게이션 설정하기

다음과 같이 createNativeStackNavigator 함수를 통해 Stack을 생성한 후 내비게이션을 설정합니다.

typescript
1import { NavigationContainer } from "@react-navigation/native";
2import { createNativeStackNavigator } from "@react-navigation/native-stack";
3import { RootStackParamList } from "./navigationTypes";
4import { HomeScreen } from "../../pages/home";
5import { SettingScreen } from "../../pages/setting";
6
7const Stack = createNativeStackNavigator<RootStackParamList>();
8
9export const Navigation = () => {
10  return (
11    <NavigationContainer>
12      <Stack.Navigator initialRouteName="Home">
13        <Stack.Screen name="Home" component={HomeScreen} />
14        <Stack.Screen name="Setting" children={SettingScreen} />
15      </Stack.Navigator>
16    </NavigationContainer>
17  );
18};
typescript
1import { Navigation } from "./routes";
2
3export const App = () => {
4  return <Navigation />;
5};

8. Step 7 - React Navigation 설정 예시

React Navigation을 설정한 예시는 다음과 같습니다.

React Navigation 설정 예시

9. 참고 자료

© HyunJinNo. Some rights reserved.