해당 글에서는 React-native에서 페이지 별 이동을 위한 Navigation 구성에 대해 이해를 돕기 위해 작성한 글입니다.
1) React Native Navigation
💡 React Native Navigation
- React Native 애플리케이션의 ‘페이지 이동’을 하는 내비게이션을 관리하고 구현하는 데 도움이 되는 라이브러리입니다. 이 라이브러리는 React Native의 다양한 기능을 활용하여 내비게이션을 관리하며, iOS와 Android를 모두 지원합니다.
- Stack Navigation, Tab Navigation 및 Drawer Navigation과 같은 다양한 타입의 네비게이션을 제공합니다. 각각의 내비게이션 타입은 사용자의 요구에 따라 선택할 수 있습니다. - 또한 React Native Navigation은 다양한 옵션을 제공하여 사용자 정의를 할 수 있습니다.
2) Navigation 종류
1. StackNavigator
💡 StackNavigator - ‘스택 형태’로 화면 위에 새로운 화면을 쌓아서 탐색을 하는 네비게이션 컴포넌트를 의미합니다. - 스택 형태로 쌓아두기에 이전 화면으로 되돌아 갈 수 있으며 탐색 히스토리를 유지하는 특징을 가지고 있습니다. 그렇기에 주로 탐색이 많은 애플리케이션에 적합합니다. - 예를 들어, A 화면에서 버튼을 누르면 B 화면으로 이동하고, B 화면에서 다시 버튼을 누르면 A 화면으로 돌아오는 경우에 사용할 수 있습니다. - 기본적으로 스택 네비게이터는 iOS에서는 새 화면으로 이동 시 오른쪽에서 슬라이드 되고 Andriod에서는 OS 기본 애니메이션이 사용됩니다. (* 해당 애니메이션을 사용자의 선택으로 정의할 수 있음)
# Stack Navigation을 설치합니다.
$ yarn add @react-navigation/stack @react-navigation/native
# 제스쳐 핸들러를 설치합니다.
$ yarn add react-native-gesture-handler
# 디자인 효과를 넣을 수 있도록 라이브러리 추가
$ yarn add @react-native-masked-view/masked-view
2. TabNavigator
💡 TabNavigator - 탭 형태로 화면을 전환하는 네비게이션 컴포넌트입니다.
- 예를 들어, 메뉴화면에서 탭을 선택하면 해당하는 화면으로 전환되는 경우에 사용할 수 있습니다.
yarn add @react-navigation/bottom-tabs
3. DrawerNavigator
💡 DrawerNavigator 란?
- 슬라이딩 형태로 화면을 전환하는 네비게이션 컴포넌트입니다.
- 예를 들어, 메뉴화면에서 왼쪽에서 슬라이딩으로 화면을 띄우면 해당하는 화면으로 전환되는 경우에 사용할 수 있습니다.
# drawerNavigator를 설치합니다.
$ yarn add @react-navigation/drawer
# 제스쳐 핸들러, 애니메이션 구현을 위해 설치합니다.
$ yarn add react-native-gesture-handler react-native-reanimated
[ 더 알아보기 ]
💡 세 개의 네비게이션에 대해서 같이 사용할 수 있는가?
- 하나의 네비게이션 컴포넌트 내에서 함께 사용할 수 있습니다. 이를 StackNavigator 안에 TabNavigator와 DrawerNavigator를 추가하는 방식으로 구현할 수 있습니다.
3) Stack Navigation 구현하기
라이브러리
버전
분류
react-native-cli
-
기본
react-native
0.70.6(latest)
기본
react
17.0.2 → 18.2.0(latest)
기본
typescript
4.8.3(latest)
기본
metro-bundler
0.72.3(latest)
기본
@react-navigation/native
6.1.6
Navigation
@react-navigation/stack
6.3.16
Navigation
react-native-gesture-handler
2.8.0
Navigation
@react-native-masked-view/masked-view
0.2.9
Navigation
react-native-safe-area-context
4.5.3
Navigation
1. 라이브러리를 설치합니다
💡라이브러리를 설치합니다.
- StackNavigation을 구현하기 위한 라이브러리를 설치합니다.
# Stack Navigation을 설치합니다.
$ yarn add @react-navigation/stack @react-navigation/native
# 제스쳐 핸들러를 설치합니다.
$ yarn add react-native-gesture-handler
# 디자인 효과를 넣을 수 있도록 라이브러리 추가
$ yarn add @react-native-masked-view/masked-view
# 안전 영역에 대한 정보를 제공하는 라이브러리입니다. 안전 영역은 디바이스 스크린의 테두리 주변에 위치한 일부 영역을 말합니다.
$ yarn add react-native-safe-area-context
2. Navigation 관리를 위한 폴더 및 파일을 생성합니다
3. CreateNavigation을 구성합니다.
import React from 'react'
import { NavigationContainer } from '@react-navigation/native';
/**
* StackNavigator를 이용하여서 앱에 대한 페이지 이동을 관리합니다.
*/
const StackNavigation = () => {
// RootStackPageList에서 페이지를 관리합니다
const Stack = createStackNavigator<CommonType.RootStackPageList>();
}
💡 [참고] Navigation 페이지를 관리하기 위해서 Type을 구성하였습니다.
/**
* 공통 타입을 관리하는 모듈
*/
export declare module CommonType {
/**
* StackNavigation 관리하는 화면들
*/
export type RootStackPageList = {
default: undefined;
home: undefined;
adminScreen: undefined;
};
}
4. StackNavigationOption을 지정합니다.
import React from 'react'
import { NavigationContainer } from '@react-navigation/native';
/**
* StackNavigator를 이용하여서 앱에 대한 페이지 이동을 관리합니다.
*/
const StackNavigation = () => {
// RootStackPageList에서 페이지를 관리합니다
const Stack = createStackNavigator<CommonType.RootStackPageList>();
const customStackNavigationOptions: StackNavigationOptions = {
gestureEnabled: false,
title: '',
headerStyle: {
backgroundColor: '#209bec',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
}
}
}
옵션(속성)
타입
설명
headerShown
boolean
헤더를 표시할지 여부를 결정합니다
headerTitle
string or React element
헤더에 표시될 제목
headerTitleAlign
string
헤더 제목의 정렬 방법 설정. 'center', 'left', 'right' 중 하나 선택 가능
headerTintColor
string
뒤로 가기 버튼과 제목 텍스트의 색상
headerBackTitle
string or React element
뒤로 가기 버튼 제목 또는 컴포넌트로 사용될 텍스트
headerStyle
object
헤더의 스타일 객체
headerTitleStyle
object
헤더 제목의 스타일 객체
headerLeft
function or React element
헤더 왼쪽에 렌더링 될 컴포넌트
headerRight
function or React element
헤더 오른쪽에 렌더링 될 컴포넌트
headerBackImage
function or React element
뒤로 가기 버튼 이미지로 사용할 커스텀 컴포넌트
gestureEnabled
boolean
화면에서 제스처를 사용할지 여부를 결정합니다
gestureDirection
string
제스처의 방향을 설정합니다. 'horizontal', 'vertical', 'inverted', 'default' 중 하나 선택 가능
cardStyle
object
카드의 스타일 객체
cardShadowEnabled
boolean
카드에 그림자를 표시할지 여부를 결정합니다
cardOverlayEnabled
boolean
카드 위에 오버레이를 표시할지 여부를 결정합니다
cardStyleInterpolator
function
카드의 스타일을 보간하는 함수
gestureResponseDistance
object
제스처 응답이 트리거되는 화면 가장자리에서의 거리
headerStatusBarHeight
number
헤더의 상태 표시 줄 높이
headerTranslucent
boolean
헤더가 투명한지 여부를 결정합니다
headerBackground
function or React element
헤더 배경으로 사용될 커스텀 컴포넌트
headerRightContainerStyle
object
오른쪽 헤더 컴포넌트 컨테이너의 스타일 객체
headerLeftContainerStyle
object
왼쪽 헤더 컴포넌트 컨테이너의 스타일 객체
headerBackgroundTransitionPreset
string
헤더 배경 전환 프리셋
headerBackTitleVisible
boolean
뒤로 가기 버튼 제목이 표시되는지 여부를 결정합니다
5. 각각의 페이지를 Navigation에 등록합니다
import React from 'react'
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator, StackNavigationOptions } from '@react-navigation/stack';
import { CommonType } from 'types/common/CommonType';
import Home from 'screens/Home';
import AdminScreen from 'screens/admin/AdminScreen';
/**
* StackNavigator를 이용하여서 앱에 대한 페이지 이동을 관리합니다.
*/
const StackNavigation = () => {
// RootStackPageList에서 페이지를 관리합니다
const Stack = createStackNavigator<CommonType.RootStackPageList>();
const customStackNavigationOptions: StackNavigationOptions = {
gestureEnabled: false,
title: '',
headerStyle: {
backgroundColor: '#209bec',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
}
}
return (
<NavigationContainer>
<Stack.Navigator initialRouteName={"home"} screenOptions={customStackNavigationOptions}>
{/* 메인 페이지 */}
<Stack.Screen name="home">
{(props) => <Home {...props} />}
</Stack.Screen>
{/* 관리자 페이지 */}
<Stack.Screen name="adminScreen">
{(props) => <AdminScreen {...props} />}
</Stack.Screen>
</Stack.Navigator>
</NavigationContainer >
)
}
export default StackNavigation;
💡 안드로이드 디바이스로 빌드를 하는 도중에 에러가 발생하였습니다. 💡 빌드 도중 react-native-gesture-handler 라이브러리 내에서 발생하는 문제점으로 판단이 되었습니다.
error Failed to install the app. Make sure you have the Android development environment set up: https://reactnative.dev/docs/environment-setup.
Error: Command failed: ./gradlew app:installDebug -PreactNativeDevServerPort=8081
e: /Users/lee/Desktop/workspace/tugboat/tugboat-rn/node_modules/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt: (247, 92): Unresolved reference: TIRAMISU
FAILURE: Build completed with 2 failures.
1: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':react-native-gesture-handler:compileDebugKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction
> Compilation error. See log for more details
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
==============================================================================
2: Task failed with an exception.
-----------
* What went wrong:
java.lang.StackOverflowError (no error message)
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
==============================================================================
문제점-1의 해결책
💡 저는 구글링을 하는 도중에 compileSdkVersion, targetSdkVersion 버전을 33으로 올리면 해결된다는 글을 발견하여서 이를 적용하였습니다.