5장
네비게이션
한 창에서 다른 창 이동할 때에 관한 내용
사이드 바(드로어)를 만들 수도 있다.
상단, 하단 탭으로 만들어서 이동
여러 화면으로 구성된 애플리케이션을 만들려면 내비게이션(navigation) 관련 서드 파티 라이브러리를 사용
종류는 아래와 같다.
- react-navigation: 리액트 네이티브 커뮤니티에서 관리, 사용률이 가장 높은 라이브러리.
리액트 공식 매뉴얼에서도 이 라이브러리로 화면을 전환하는 방법을 소개
내비게이션 기능이 자바스크립트로 구현 - react-native-navigation: 홈페이지 제작 서비스 Wix에서 관리
이미 만들어진 네이티브 앱에 리액트 네이티브를 적용하는 경우 사용하기에 더 적합
내비게이션 기능이 각 플랫폼의 네이티브 코드로 구현
아래의 구문을 터미널에 쳐서 @react-navigation/native 모듈을 설치
위치는 새로 생성한 프로젝트 디렉터리로 들어가서 설치한다.
yarn add @react-navigation/native
의존 라이브러리는 아래의 구문으로 설치
yarn add react-native-screens react-native-safe-area-context
리액트 네이티브 프로젝트에 라이브러리를 적용하기 위해서는
@react-navigation/native에서 NavigationContainer 컴포넌트를 불러와 사용해 아래처럼 앱 전체를 감싸주어야 함
import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
function App() {
return <NavigationContainer>{/* 내비게이션 설정 */}</NavigationContainer>;
}
export default App;
웹 브라우저에 탑재된 History 기능이 있어
<a href="https://google.com">구글</a> 같은 태그를 사용해 주소로 이동,
뒤로 가기, 앞으로 가기 가 가능하다.
History는 스택(Stack) 자료구조를 사용해 구현.
스택 자료구조는 새로운 항목을 추가할 때 맨 위에 쌓이고, 맨 위에 있는 항목을 추출
=> 네이티브 스택 내비게이터(Native Stack Navigator)도 같은 방식이다.
네이티브 스택 내비게이터(Native Stack Navigator)
가장 흔히 사용되며 안드로이드에서는 Fragment를,
iOS에서는 UINavigationController를 사용해
일반 네이티브 앱과 정확히 동일한 방식으로 화면을 관리
설치는 아래 구문을 치면 된다.
yarn add @react-navigation/native-stack
네이티브 스택 내비게이터는 아래처럼
createNativeStack Navigator라는 함수를 사용해 만들 수 있다.
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Detail" component={DetailScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
위의 구문에서 보듯
Stack은
Stack.Navigator라는 컴포넌트 / Stack.Screen 컴포넌트가 들어있음.
Stack.Navigator 컴포넌트는 NavigationContainer 사이에 넣어야 정상 작동
Stack.Screen 컴포넌트를 사용해 각 화면을 설정.
이 컴포넌트들에 설정된 name(위에서는 Home, Detail)은 화면의 이름을 설정하는 Props.
현재 화면이 어떤 화면인지 조회할 때 사용(대문자로 시작 권장).
아래의 구문은 네이티브 스택 내비게이터를 사용할 때 화면 전환할 때의 방법이다.
push / navigate는 약간의 차이가 있다.
push는 다른 화면으로 넘어가면서(화면이 새로 쌓이면서) 파라미터를 하나 증가한다고 가정 하면
새로운 화면이 생기면서 증가한 파라미터를 보여주지만
navigate는 push와 달리 새로 이동할 화면이 현재 화면과 같으면
새로운 화면이 따로 생기지 않고(화면이 안쌓임) 파라미터만 변경
그래서 뒤로 가기를 하면 push는 이전 화면을 보여주지만
navigate는 바로 첫화면이 떠버림
마지막으로 push는 네이티브 스택 내비게이터에서만 사용 가능
<Button
title="Detail 열기"
onPress={() => navigation.push('Detail')}
/>
<Button
title="Detail 열기"
onPress={() => navigation.navigate('Detail')}
/>
라우트 파라미터는 새로운 화면을 보여줄 때 의존해야 하는 어떤 값이다.
아래처럼 navigate 또는 push 함수의 두 번째 인자로 객체를 설정한다.
navigation.navigate('Detail', {id: 1})
route의 속성은 아래와 같다. : 뒤의 내용은 임의의 내용.
- key는 화면의 고유 ID로 새로운 화면이 나타날 때 자동으로 생성.
- name은 화면의 이름
- params가 라우트 파라미터
{
"key": "Detail-vgDx8-H-8e7oao6a3xJz7",
"name": "Detail",
"params": {"id": 1}
}
뒤로가기 : navigation.pop() 함수를 호출
가장 첫 번째 화면으로 이동 : navgiation.popToTop() 함수를 호출
헤더 커스터마이징하는 방법
1. Stack.Screen의 Props로 설정
2. 화면 컴포넌트(헤더 내용이 들어 있는 function)에서 navigation.setOptions 함수를 사용
useEffect를 통해서 설정한 내비게이션 option은 App 컴포넌트에서 Props를 통해 설정한 option을 덮어 씀.
모든 화면에서 헤더를 없애고 싶다
<Stack.Navigator
initialRouteName="Home"
screenOptions={{
headerShown: false,
}}>
드로어 내비게이터(Drawer Navigator)는 좌측 또는 우측에 사이드바를 만들고 싶을 때 사용하는 내비게이터
사이드바를 모바일 앱에서는 드로어(Drawer)라고 부른다.
설치 구문은 아래와 같다.
yarn add @react-navigation/drawer react-native-gesture-handler react-native-reanimated
createDrawerNavi gator 함수를 만들어 Drawer 객체를 만든다.
이 안에는 Navigator와 Screen이 들어있는데 이를 컴포넌트로 사용.
initialRouteName Props : 내비게이터에서 기본적으로 보여줄 화면의 이름. 이 값이 없다면 맨 위에 있는 화면(Home)이 뜸.
drawerPosition Props : 드로어가 나타나는 위치. 값을 "left" 또는 "right"로 지정. 기본값은 "left"
backBehavior Props : 뒤로가기를 할 때 어떻게 작동할지 설정
이 Props에 지정할 수 있는 값은 다음과 같다.
- initialRoute: 가장 첫 번째 화면을 보여줌.
- order: Drawer.Screen 컴포넌트를 사용한 순서에 따라 현재 화면의 이전 화면을 보여줌.
- history: 현재 화면을 열기 직전에 봤던 화면을 보여줌.
- none: 뒤로가기를 수행하지 않음.
navigation.navigate 함수 : 사용자 행동(예를 들어, 버튼 클릭)에 따라 다른 화면으로 이동
navigation.goBack 함수 : 뒤로가기를 하고 싶을 때
Drawer의 스타일
Drawer.Navigator 컴포넌트에 screenOptions Props를 설정하면 스타일을 건드릴 수 있다.
- drawerActiveTintColor: 활성화된 항목의 텍스트 색상
- drawerActiveBackgroundColor: 활성화된 항목의 배경색
- drawerInactiveTintColor: 비활성화된 항목의 텍스트 색상
- drawerInactiveBackgroudnColor: 비활성화된 항목의 배경색
- drawerItemStyle: 항목의 스타일
- drawerLabelStyle: 항목 내부의 텍스트 스타일
- drawerContentContainerStyle: 항목들을 감싸고 있는 영역의 스타일
- drawerStyle: 전체 드로어를 감싸고 있는 영역의 스타일
하단 탭 내비게이터를 사용하기 위해선
라이브러리를 추가로 설치가 필요하다
아이콘도 필요하므로 아이콘을 편리하게 사용할 수 있도록 react-native-vector-icons 라이브러리를
아래 구문으로 설치
yarn add @react-navigation/bottom-tabs react-native-vector-icons
그리고 사용 전 아래의 구문을 넣어준다
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
그 후 아이콘을 사용하기 위해 아래 파일에 아래 구문을 넣어준다.
android/app/build.gradle - 최하단
project.ext.vectoricons = [
iconFontNames: [ 'MaterialIcons.ttf' ]
]
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
ios/LearnReactNavigation/Info.plist - 최하단
(...)
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIAppFonts</key>
<array>
<string>MaterialIcons.ttf</string>
</array>
</dict>
</plist>
하단 탭 커스터마이징
screenOptions Props를 통해 설정한다.
- tabBarActiveTintColor: 활성화된 항목의 아이콘과 텍스트 색상
- tabBarActiveBackgroundColor: 활성화된 항목의 배경색
- tabBarInactiveTintColor: 비활성화된 항목의 아이콘과 텍스트 색상
- tabBarInactiveBackgroundColor: 비활성화된 항목의 배경색
- tabBarShowLabel: 항목에서 텍스트의 가시성 설정(기본값: true)
- tabBarShowIcon: 항목에서 아이콘의 가시성 설정(기본값: false)
- tabBarStyle: 하단 탭 스타일
- tabBarLabelStyle: 텍스트 스타일
- tabBarItemStyle: 항목 스타일
- tabBarLabelPosition: 텍스트 위치 'beside-icon'(아이콘 우측) / 'below-icon'(아이콘 하단)
- tabBarAllowFontScaling: 시스템 폰트 크기에 따라 폰트 크기를 키울지 결정(기본값: true)
- tabBarSafeAreaInset: SafeAreaView의 forceInset 덮어쓰는 객체(기본값: {bottom: 'always', top: 'never'})
- tabBarKeyboardHidesTabBar: 키보드가 나타날 때 하단 탭을 가릴지 결정(기본값: false)
하단 탭 내비게이터를 네이티브 스택 내비게이터 내부에서 사용하게 될 때
options에 headerShown 값을 false로 해야한다.
만약 이 값을 설정하지 않는다면 두 개의 헤더가 나타나는 문제가 발생
머티리얼 상단 탭 내비게이터(Material Top Tab Navigator)
탭을 상단에 위치하게 한다.
기존에 다룬 내비게이터와 다르게 헤더를 보여주지 않는다.
설치를 위한 구문은 아래와 같다.
yarn add @react-navigation/material-top-tabs react-native-tab-view react-native-pager-view
해당 네비게이터는 아이콘 크기를 자체적으로 지정해주지 않는다.
옵션의 종류는 아래와 같다.
- initialRouteName: 초기 화면의 이름
- screenOptions: 화면의 기본 설정. 하단 탭 내비게이션과 비슷한데, 다음과 같은 추가 옵션이 있다.
– swipeEnabled: 화면을 좌우로 스와이프하여 전환 가능하게 함(기본값: true).– lazy: 특정 탭으로 이동해야만 해당 탭을 렌더링(기본값: true).– lazyPlaceholder: lazy 속성이 활성화되어 있을 때 아직 보이지 않은 화면에서 보여줄 대체 컴포넌트– tabBarIndicatorStyle: 활성화된 탭을 표시하는 컴포넌트의 스타일 - – tabBarIndicator: 활성화된 탭을 표시하는 컴포넌트
- – lazyPreloadDistance: lazy 속성이 활성화된 상태에서 몇 칸 뒤 화면을 미리 불러올지 설정(기본값: 0).
- backBehavior: 뒤로가기할 때의 작동 방식
- tabBarPosition: 탭 바의 위치(top 또는 bottom)
- keyboardDismissMode: 키보드를 숨기는 설정– auto: 기본값. 화면이 바뀔 때 키보드를 숨김.– none: 드래그해도 키보드를 숨기지 않음.
- – on-drag 화면을 드래그할 때 키보드를 숨김.
- sceneContainerStyle: 각 화면에 대한 스타일
- style: 전체 탭 뷰에 대한 스타일
- tabBar: 탭 바를 대체할 수 있는 컴포넌트(공식 매뉴얼 참조)
Tab.Screen의 options Props에는 아래의 값 설정 가능
- tabBarIcon: 아이콘을 보여주는 함수, { focused: boolean, color: string } 타입의 파라미터를 받음.
- tabBarLabel: 탭에서 보이는 이름
머티리얼 하단 탭 내비게이터(Material Bottom Tab Navigator)
머티리얼 상단 탭 내비게이터와 달리 하단에만 나타난다.
활성화된 탭에 따라 전체 탭의 배경색을 변경 가능
Tab.Navigator 컴포넌트에는 다음과 같은 Props를 지정해줄 수 있다.
(Tab은 Material Bottom Tab Navigator를 담은 변수)
- initialRouteName: 초기 화면의 이름
- screenOptions: 화면의 기본 설정
- backBehavior: 뒤로가기할 때의 작동 방식
- shifting: 이 값이 true로 지정되어 있으면 탭이 변경될 때마다 배경색을 변경, 활성화된 탭만 탭의 이름을 보여줌.
탭의 개수가 세 개 이상이면 이 값은 기본적으로 true로 설정.
만약 이 값을 false로 지정하면 탭마다 배경색을 따로 따로 지정할 수 없고, 모든 탭에 이름이 보이게 됨. - labeled: 탭 아이콘 하단에 탭의 이름을 나타낼지 정하는 값.
이 값을 false로 지정하면 모든 탭에 이름이 나타나지 않음(기본값: true). - activeColor: 활성화된 탭의 아이콘과 텍스트의 색상
- inactiveColor: 비활성화된 탭의 아이콘과 텍스트의 색상
- barStyle: 탭 바에 스타일 적용
Tab.Screen의 options Props에는 다음과 같은 값을 설정할 수 있다.
- tabBarIcon: 아이콘을 보여주는 함수, { focused: boolean, color: string } 타입의 파라미터를 받는다.
- tabBarLabel: 탭에 보이는 이름
- tabBarBadge: 탭 아이콘에 배지를 보여줌.
값을 true로 설정하면 아이콘 우측 상단에 빨간색 점을 보여줌.
값을 문자열 또는 숫자로 입력하면 그 내용이 배지에 나타남.
머티리얼 하단 탭 내비게이터에서 선택된 탭과 헤더의 타이틀을 동기화하는 방법
getFocused RouteNameFromRoute 함수는 route 객체를 통하여 현재 포커스된 화면의 이름을 조회
?? ( nullish 병합 연산자) : 연산자 좌측에 있는 값이 null이거나 undefined면 우측의 값으로 설정
Hooks
- useNavigation Hook을 사용하면 Screen으로 사용되고 있지 않은 컴포넌트에서도 navigation 객체를 사용 가능
- useRoute는 useNavigation과 비슷하게, Screen이 아닌 컴포넌트에서 route 객체를 사용 가능
- useFocusEffect는 화면에 포커스가 잡혔을 때 특정 작업을 할 수 있게 하는 Hook
다른 화면을 열었다가 돌아왔을 때 특정 작업을 하고 싶다면 사용.
현재 화면에서 다른 화면으로 넘어갈 때 특정 작업을 하고 싶다면 useFocusEffect에서 함수를 만들어 반환
useFocusEffect는 꼭 useCallback과 같이 사용.
만약 useCallback을 사용하지 않으면 컴포넌트가 리렌더링될 때마다 useFocusEffect에 등록한 함수가 호출useCallback은 컴포넌트 내부에서 함수를 만들 때, 새로 만든 함수를 사용하지 않고 이전에 만든 함수를 다시 사용하도록 만들어 줌. 그 함수 내부의 로직에서 의존하는 값이 있다면 의존하는 값이 바뀌었을 때 함수를 교체할 수 있도록 해 줌.
'프로젝트 진행 공부 > 리액트 네이티브(React Native)' 카테고리의 다른 글
7장 요점 정리 (0) | 2022.10.11 |
---|---|
6장 요점 정리 (0) | 2022.10.11 |
4장 요점 정리 (0) | 2022.10.04 |
3장 요점 정리 (0) | 2022.10.04 |
1, 2장 요점 정리 (0) | 2022.09.30 |
댓글