반응형
해당 글에서는 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;
6. 최초 시작 페이지에서 StackNavigation을 호출합니다
import React, { useEffect } from 'react';
import StackNavigation from 'screens/navigation/StackNavigation';
/**
* Main App
* @param props
* @returns
*/
const App = (props: any) => {
return (
<StackNavigation />
)
}
export default App;
7. 시작 페이지로 정의한 부분을 아래와 같이 구성하였습니다 : Home.tsx
import React, { useEffect } from "react";
import { Button, Text, View } from "react-native";
import { TouchableOpacity } from "react-native-gesture-handler";
const Home = ({ route, navigation }) => {
useEffect(() => {
}, []);
const moveAdminScreen = () => {
navigation.navigate('adminScreen');
}
return (
<View>
<TouchableOpacity onPress={moveAdminScreen}>
<Text>
관리자 페이지로 이동합니다.
</Text>
</TouchableOpacity>
</View>
)
}
export default Home;
7. 호출한 페이지로 정의한 부분을 아래와 같이 구성하였습니다 : AdminScreen.tsx
import React, { useEffect } from "react";
import { Text, View } from "react-native";
const AdminScreen = ({ route, navigation, appState }) => {
useEffect(() => {
}, []);
return (
<View>
<Text> 관리자 페이지로 이동하였습니다!!</Text>
</View>
)
}
export default AdminScreen;
4) 결과화면
💡 최초 페이지와 버튼을 눌렀을 때 페이지 이동함을 확인하였습니다.
99) 참고
문제점-1
💡 안드로이드 디바이스로 빌드를 하는 도중에 에러가 발생하였습니다.
💡 빌드 도중 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으로 올리면 해결된다는 글을 발견하여서 이를 적용하였습니다.
buildscript {
ext {
buildToolsVersion = "33.0.0"
minSdkVersion = 21
compileSdkVersion = 33
targetSdkVersion = 33
}
}
문제점-2
Error: Requiring unknown module "undefined". If you are sure the module exists, try restarting Metro. You may also want to run yarn or npm install
문제점-2의 해결책-2
💡 해결책으로 아래의 라이브러리를 설치합니다
$ yarn add react-native-screens
# + PLUS
$ yarn add react-native-vector-icons
# 그래도 안된다 하면 node_modules를 제거하고 설치합니다.
$ rm -r node_modules/
# yarn 설치
$ yarn
💡 참고 문서
오늘도 감사합니다. 😀
반응형
'React & React Native > 라이브러리 활용' 카테고리의 다른 글
[RN] ONNX(Open Neural Network Exchange) 이해하기 -2 : ONNX 모델 불러오기 (0) | 2023.06.12 |
---|---|
[RN] ONNX(Open Neural Network Exchange) 이해하기 -1: React Native 활용 (2) | 2023.06.10 |
[RN] react-native-cli에서 expo-cli 모듈 사용하기 (0) | 2022.05.15 |
[RN] React Native 자이로센서를 활용한 자이로스코프, 디바이스 모션 이해하기: expo-sensors (0) | 2022.05.15 |
[RN] React Native Tensorflow.js 메모리 관리 이해하기 (0) | 2022.04.10 |