화면 전환 기능
새로운 화면을 최상단에 배치함 (스택 자료구조 떠올려라)
스택 네비게이터 구현 모습
기본적으로 스택 네비게이터는 익숙한 iOS와 Android의 모양과 느낌을 갖도록 구성된다.
default
- iOS : 새로운 화면은 오른쪽에서 왼쪽으로 나타난다.
- Android : 새로운 화면은 아래에서 위로 올라온다.
optional
- iOS : 안드로이드처럼 새 화면이 아래에서 위로 올라오도록 modal style로도 설정 가능하다.
패키지 설치
#작업하고 있는 react-native 패키지 폴더로 이동해서 설치해야함. (프로젝트가 바뀌면 매번 다시 설치) #npm을 쓰고 있다면 $ npm install @react-navigation/stack #yarn을 쓰고 있다면 $ yarn add @react-navigation/stack
*****필수***** (react-native-gesture-handler)
//이제 index.js 혹은 App.js의 최상단에 아래와 같이 적어주면 된다. //반드시 최상단에 적어야함 (위에 아무것도 없이) //생략하면 개발 시에는 정상동작 할 지라도, production에서 crash가 나므로 중요!! import 'react-native-gesture-handler';
기본 사용법
import React from 'react'; import { createStackNavigator } from '@react-navigation/stack'; const Stack = createStackNavigator(); function MyStack() { return ( <Stack.Navigator> <Stack.Screen name="Home" component={Home} /> <Stack.Screen name="Notifications" component={Notifications} /> <Stack.Screen name="Profile" component={Profile} /> <Stack.Screen name="Settings" component={Settings} /> </Stack.Navigator> ); }
기본적인 틀은 대충 이런 식인데, 아래 예시를 보는 게 더 이해가 잘 될 듯.
import 'react-native-gesture-handler'; //이거 필수라고 앞에서 말했다! import * as React from 'react'; import { Button, View } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; function HomeScreen({ navigation }) { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Button title="Go to Profile" onPress={() => navigation.navigate('Profile')} /> </View> ); } function ProfileScreen({ navigation }) { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Button title="Go to Notifications" onPress={() => navigation.navigate('Notifications')} /> <Button title="Go back" onPress={() => navigation.goBack()} /> </View> ); } function NotificationsScreen({ navigation }) { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Button title="Go to Settings" onPress={() => navigation.navigate('Settings')} /> <Button title="Go back" onPress={() => navigation.goBack()} /> </View> ); } function SettingsScreen({ navigation }) { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Button title="Go back" onPress={() => navigation.goBack()} /> </View> ); } const Stack = createStackNavigator(); function MyStack() { return ( <Stack.Navigator> <Stack.Screen name="Home" component={HomeScreen} /> <Stack.Screen name="Notifications" component={NotificationsScreen} /> <Stack.Screen name="Profile" component={ProfileScreen} /> <Stack.Screen name="Settings" component={SettingsScreen} /> </Stack.Navigator> ); } export default function App() { return ( <NavigationContainer> <MyStack /> </NavigationContainer> ); }
Props
Stack.Navigator 컴포넌트는 아래의 Props들을 받을 수 있다.
: 스택 네티게이터의 맨 처음 요소가 가장 먼저 뜨는데, 별도로 첫 화면을 지정할 수 있다.
<Stack.Navigator initialRouteName='Home'> <Stack.Screen name="Notifications" component={NotificationsScreen} /> <Stack.Screen name="Home" component={HomeScreen} /> <Stack.Screen name="Profile" component={ProfileScreen} /> <Stack.Screen name="Settings" component={SettingsScreen} /> </Stack.Navigator>
keyboardHandlingEnabled
:
false
일 경우 새 화면으로 이동할 때 화면 키보드가 자동으로 해제되지 않는다. 기본값은 true
(키패드 입력한다고 떠있는 키보드 말하는듯)
mode
스크린이 어떻게 렌더링되고 전환되는 지 모드 설정.
card
: 표준 iOS와 android 화면 전환을 사용. default 옵션임.
modal
: 별도로 명시하지 않았다면
headerMode
를 screen
으로 설정하고,: iOS에서도 안드로이드처럼 새로운 화면이 아래에서 위로 올라오도록 설정됨.
headerMode
헤더가 어떻게 렌더링 될 지 설정.
float
: iOS의 전형적인 패턴. 헤더 위치는 그대로 고정된 채 내용만 바뀜.
screen
: android의 전형적인 패턴. 스크린이랑 일체되어 같이 이동하는 것처럼 보임.
none
: 헤더를 출력하지 않음.
screenOptions
: navigator에 속한 스크린들에 적용될 옵션들을 지정할 수 있는데, 너무 많으므로 별도 정리하지 않음.
공식문서의 Options 부분 참조.
Events
특정 액션에서 event를 발생시킨다.
transitionStart
현재 화면에서 화면 전환 애니메이션이 시작될 때 이벤트가 발생함.
React.useEffect(() => { const unsubscribe = navigation.addListener('transitionStart', (e) => { //여기에 이벤트 발생 시 취할 행동을 적으면 됨. }); return unsubscribe; }, [navigation]);
transitionEnd
현재 화면에서 전환 애니메이션이 종료될 때 이벤트가 발생함.
React.useEffect(() => { const unsubscribe = navigation.addListener('transitionEnd', (e) => { //여기에 이벤트 발생 시 취할 행동을 적으면 됨. }); return unsubscribe; }, [navigation]);
Helpers
stack navigator는 navigation prop에 다음과 같은 메소드를 더한다.
push
새로운 스크린을 스택의 최상단에 push하고 이동한다.
push 메소드는 다음의 파라미터를 수용한다.
name
- string : 스택에 푸시할 경로 이름.
params
- object : 대상 경로에 병합할 화면 매개 변수
function HomeScreen({ navigation }) { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> {//화면 전환시 상위에 쌓긴 하지만, 똑같은 화면을 계속 쌓아가진 않음.} <Button title="Go to Profile" onPress={() => navigation.navigate('Profile')} /> {//동일한 화면이어도 계속해서 화면 위에 화면으로 스택을 쌓아감.} <Button title="Push to Profile" onPress={() => navigation.push('Profile')} /> </View> ); }
- navigation.navigate('Home')
- navigation.navigate('Profile')
- navigation.push('Home')
- navigation.push('Profile')
push 한만큼 뒤로 가야 첫 스크린에 도달
pop
push의 반대로, 스택에 쌓인 스크린들을 꺼내는 것.
count
인자로 한번에 몇개의 스크린을 pop 할 건지 지정할 수 있다.navigation.pop(); //스크린 하나 pop navigation.pop(3); //3개 스크린 한번에 pop
13개의 스크린을 push하고
pop(10)으로 한번에 10개의 스크린을 팝했더니
첫 화면으로 가려면 3개의 스크린만 뒤로가기 하면 된다.
popToTop()
모~~든 스크린을 pop하고 젤 첫 화면으로 이동함.
function ProfileScreen({ navigation }) { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Button title="Push to Home" onPress={() => navigation.push('Home')} /> <Button title="Pop All Screens !" onPress={() => navigation.popToTop()}/> </View> ); }
몇 개인지도 모를만큼 스크린을 push 했는데,
popToTop() 한번이면 모든 화면을 pop하고 초기화면으로 이동할 수 있다.
Animations
스크린이 추가되고 삭제될 때의 전환 애니메이션을 설정할 수 있다.
각각의 스크린의
options
prop을 지정하여 스크린별로 애니메이션을 다르게 할 수 있다.당장 중요하진 않으므로 생략.
자세한 건 도큐먼트 하단 Animations 부분 참조