🧩Javascript/react-native

React Native 네비게이션 사용하기(feat typescript)

DevJiun 2022. 5. 21. 16:27

대부분의 앱에서는 화면간 이동이 필요합니다.

플러터와 달리 리액트 네이티브에선 서드파티에 의존해서 해당 기능을 구현해야 합니다.

 

우선 필요한 라이브러리들을 설치해주겠습니다.

 

yarn add @react-navigation/native react-native-screens react-native-safe-area-context @react-navigation/native-stack

 

App.tsx를 NavigationContainer로 감싸주어야 사용할 수 있습니다.

 

import React from "react";
import { NavigationContainer } from "@react-navigation/native";

function App() {
  return (
    <NavigationContainer>{}</NavigationContainer>
  );
}

export default App;

그리고 네이티브 스택 네비게이션을 생성해주어야 합니다.

 

screens 디렉토리 내에 RootStack.tsx 파일을 생성해줍니다.

그리고 아래와 같이 코드를 작성해주겠습니다.

import React from "react";
import { Button, Text, View } from "react-native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { useNavigation } from "@react-navigation/native";

const Stack = createNativeStackNavigator();

function HomeScreen(){
    const navigation = useNavigation();
    const onPress = () => {
        navigation.navigate('Detail');
    };

    return (
        <View>
            <Text>Home</Text>
            <Button title="Open Detail" onPress={onPress} />
        </View>
    );
}

function DetailScreen(){
    return (
        <View>
            <Text>Detail</Text>
        </View>
    );
}

function RootStack(){
    return (
        <Stack.Navigator>
            <Stack.Screen component={HomeScreen} name='Home' />
            <Stack.Screen component={DetailScreen} name='Detail' />
        </Stack.Navigator>
    );
}

export default RootStack;

화면은 HomeScreen, DetailScreen 두개의 스크린을 만들어주었습니다.

물론 다른 경로에 작성하신 후 import로 가져오셔도 됩니다. 간단한 예제이므로 한 파일안에 작성해주었습니다.

 

createNativaStackNavigator를 생성해 준 후 RootStack에 네비게이터를 사용할 화면을 정의해줍니다.

그 후 아래 코드로 이동이 가능합니다.

navigation.navigate('Home');
navigation.navigate('Detail');

저희는 타입스크립트로 프로젝트를 생성했기 때문에 navigation.navigate('Detail'); 부분에서 오류가 나고 있으실 겁니다.

 

사용할 화면의 타입을 지정해주어야 합니다.

아래코드를 작성해줍니다.

type RootStackParamList = {
    Home: undefined;
    Detail : {
        id: number;
    };
};

const Stack = createNativeStackNavigator<RootStackParamList>();

 

이때 타입스크립트의 장점이 보입니다. RootStack내에 정의되지 않은 화면을 추가하려고 하면 오류가 발생합니다.

 

useNavigation을 사용할 때 NavigationProp를 선언해주어야 합니다.

아래와 같이 코드를 작성해줍니다.

// 추가
export type RootStackNavigationProp = NativeStackNavigationProp<RootStackParamList>;

// 수정
function HomeScreen(){
    const navigation = useNavigation<RootStackNavigationProp>();
    const onPress = () => {
        navigation.navigate('Detail', {id: 1});
    };

    return (
        <View>
            <Text>Home</Text>
            <Button title="Open Detail" onPress={onPress} />
        </View>
    );
}

 

Detail으로 넘어갈때 보내는 Prop을 사용하려면 useRoute가 필요합니다.

아래와 같이 코드를 작성해줍니다.

// 추가 RouteProp이 필요함.
type DetailScreenRouteProp = RouteProp<RootStackParamList, 'Detail'>;

// 수정
function DetailScreen(){
    const {params} = useRoute<DetailScreenRouteProp>();
    return (
        <View>
            <Text>Detail {params.id}</Text>
        </View>
    );
}

이제 RootStack을 App컴포넌트의   NavigatiorContainer로 감싸줍니다.

 

import React from "react";
import { NavigationContainer } from "@react-navigation/native";
import RootStack from "./screens/RootStack";

function App() {
  return (
    <NavigationContainer>
      <RootStack />
    </NavigationContainer>
  );
}

export default App;

참고자료

https://reactnavigation.org/docs/getting-started/

 

https://reactnavigation.org/docs/getting-started/

 

reactnavigation.org

리액트 네이티브를 다루는 기술 12장