FrontEnd/ReactNative

React Native에서는 어떻게 페이지 이동을 하나요? React Navigation이 있어요!

Grace 2022. 10. 26. 17:21

React-Navigation

React Native에서는 앱 내 화면 간 전환을 처리하기 위해 라이브러리로 react-navigation을 사용합니다.

React-Navigaton 설치

react navigation 설치 링크

react navigation 설치 명령어 입니다.

# npm
npm install @react-navigation/native

# yarn
yarn add @react-navigation/native

또한, react-native-screens와 react-native-safe-area-context가 있습니다.

이 라이브러리는 react navigation을 통해 탐색된 컨테이너를 앱에 노출해주기 위해 사용해야하는 종속 라이브러리입니다. 이것들을 함께 설치해주도록 하겠습니다.

# expo
expo install react-native-screens react-native-safe-area-context

# npm
npm install react-native-screens react-native-safe-area-context

# yarn
yarn add react-native-screens react-native-safe-area-context

iOS용으로 개발 중인 경우 연결을 완료하려면 Pod을 설치해야합니다.

(프로젝트 폴더에서)
npx pod-install ios

혹은

cd ios
pod install

만약 android용으로 개발 중인 경우 연결을 완료하려면 MainActivity 본문에 다음을 추가합니다.

(프로젝트 폴더)/android/app/src/main/java/(프로젝트 이름)/MainActivity.java

import android.os.Bundle;

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(null)
}

React-Navigaton 시작

React navigation 설치를 완료하고 우리 앱에서 navigation을 사용해주려면 NavigationConatiner를 만들어주어야합니다. App.js(App.tsx)에 작업하시면 됩니다.

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';

export default function App() {
  return (
    <NavigationContainer>{/* Rest of your app code */}</NavigationContainer>
  );
}

❗️참고로 이 navigationconatinaer는 app하나에 한 번만 사용해야합니다.

React-Navigation 사용

1) Stack Navigatior

stack navigator는 react-navigation에서 가장 기본적으로 사용되는 navigator입니다.

react navigation의 각 navigator는 자체 라이브러리(react-navigation)에 있습니다. stack navigator를 사용하려면 다음을 설치해야 합니다.

# npm
npm install @react-navigation/native-stack

# yarn
yarn add @react-navigation/native-stack

먼저, createNativeStackNavigator를 사용해서 Screen과 Navigator 속성을 포함하는 객체를 만들어줍니다.

Screen과 Navigator는 모두 라우팅을 구성하는 데 사용되며 경로를 정의해주기 위해서 Navigator는 Screen을 자식요소로 포함합니다.

import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

function HomeScreen() {
  return (
    <View>
      <Text>Home Screen</Text>
    </View>
  );
}

const Stack = createNativeStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
	      <Stack.Screen name="Detail" component={Detail} />
				...
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

stack에 screen이 두 개 생성되면 두 개의 route가 생성됩니다.

만약 Screen에 포함된 Component에 prop을 전달해주고 싶을 경우, React Context를 이용해서 해당 Navigator를 감싸주시는 것을 권장합니다(우리가 배웠던 recoil, contextAPI처럼). Screen에 포함된 Component에 직접 전달해주시는 방법도 있지만(렌더 콜백) 이 경우 성능 문제를 방지하려면 memo를 사용해주셔야하기 때문에 권장하는 방법은 아닙니다.

2) Routing

화면 간 이동을 해주기 위해서는 navigation을 사용해주어야 합니다.

navigation은 navigator에 포함된 모든 screen에 종속 부여되는 요소로 Screen에서 parameter로 불러와 사용할 수 있습니다.

아까 우리가 home과 details라는 두 개의 screen을 생성해주었죠? 이렇게 해서 두 개의 route가 생성되었다고 했습니다.

우리는 navigation.navigate(’name')을 사용하여 라우팅을 해줄 수 있는데, 당연하게도 이 때 라우팅 할 수 있는 경로는 생성되어진 route 에서만 가능합니다.

import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button
        title="Go to Details"
        onPress={() => navigation.navigate('Details')}
      />
    </View>
  );
}

3) Nesting navigators

Nesting navigator는 다른 네비게이터의 화면 안에 네비케이터를 렌더링하는 것입니다.

function Home() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Feed" component={Feed} />
      <Tab.Screen name="Messages" component={Messages} />
    </Tab.Navigator>
  );
}

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="Home"
          component={Home}
          options={{ headerShown: false }}
        />
        <Stack.Screen name="Profile" component={Profile} />
        <Stack.Screen name="Settings" component={Settings} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

Tab Navigator는 home stack 안에 포함되어 tab navigator에서 구성되는 요소는 home에서도 사용 가능해집니다.

이렇게 중첩되는 네비게이터를 사용할 수는 있지만,네비게이터 중첩이 깊어질 경우 아래와 같은 문제가 생길 수 있습니다.

  • 메모리 및 성능 문제를 일으킬 수 있습니다.
  • 동일한 유형의 네비게이터를 중첩하면 UX가 혼동될 수 있습니다.
  • 중첩된 화면에서 데이터가 코드를 따라가기 힘들어집니다.

때문에 별도의 구성을 만들어주고 싶다면 Group을 사용해주면 됩니다.

<Stack.Navigator>
  {isLoggedIn ? (
    // Screens for logged in users
    <Stack.Group>
      <Stack.Screen name="Home" component={Home} />
      <Stack.Screen name="Profile" component={Profile} />
    </Stack.Group>
  ) : (
    // Auth screens
    <Stack.Group screenOptions={{ headerShown: false }}>
      <Stack.Screen name="SignIn" component={SignIn} />
      <Stack.Screen name="SignUp" component={SignUp} />
    </Stack.Group>
  )}
  {/* Common modal screens */}
  <Stack.Group screenOptions={{ presentation: 'modal' }}>
    <Stack.Screen name="Help" component={Help} />
    <Stack.Screen name="Invite" component={Invite} />
  </Stack.Group>
</Stack.Navigator>

4) Passing Parameter

우리가 라우팅을 해줄 때 데이터를 전달하는 방법에 대해서 알아봅시다.

navigation.navigate 함수에 대한 두 번째 매개변수인 params 객체에 넣어 해당 경로에 전달합니다.

navigation.navigate('RouteName', {boardId: 13, isEdit: true})

그리고 라우팅된 컴포넌트에서 해당 값을 route.params로 읽어오면 됩니다. route는 navigation과 마찬가지로 navigator에 포함된 모든 screen에 종속 부여되는 요소입니다.

function RouteName({route, navigation}){
	const {boardId, isEdit} = route.params;
	console.log(boardId)   // 13
	console.log(isEdit)   // isEdit
}

Nesting Navigator가 있는 경우 약간 다르게 전달해야 합니다. 예를 들어, Account Screen 안에 Setting Screen이 있는 경우 다음 과 같이 전달해줍니다.

navigation.navigate('Account', {screen: 'Settings', params: {userId: 'codecamp6'}})

이 외에도 초기 parameter 설정, 이전 화면으로 전달하는 방법이 있으니 자세한 것은 React Navigation params 공식 문서를 참조하세요!