#11 App: Navigation
#11.1 AuthNavigation ~ #11.2 Tabs Navigation ~##11.3 Photo Navigation
리액트 네비게이션이 5.x 버전으로 업데이트되면서 강의 내용과 많은 부분이 달라졌다.
버전 문제로 에러가 너무 많이 나서, 전부 다 최신버전으로 업데이트 하였다.
일단. 설치 모듈
1. npm install @react-navigation/bottom-tabs
2. npm install @react-navigation/material-top-tabs react-native-tab-view
>components/NavController.js
import React from "react";
import { View } from "react-native";
import { useIsLoggedIn } from "../AuthContext";
import AuthNavigation from "../navigation/AuthNavigation";
import MainNavigation from "../navigation/MainNavigation";
export default () => {
const isLoggedIn = true;
return (
<View style={{ flex: 1 }}>
{isLoggedIn ? <MainNavigation /> : <AuthNavigation />}
</View>
);
};
먼저 로그인 되었을 때 화면을 만들기 위해, 임의로 isLoggedIn 값을 true로 바꿔주었다.
로그인이 되었을 때, MainNavigation이 실행된다.
>navigation/MainNavigation.js
import "react-native-gesture-handler";
import * as React from "react";
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import TabNavigation from "./TabNavigation";
import PhotoNavigation from "./PhotoNavigation";
const MainNavigation = createStackNavigator();
export default () => {
return (
<NavigationContainer>
<MainNavigation.Navigator>
<MainNavigation.Screen name="TabNavigation" component={TabNavigation} />
<MainNavigation.Screen
name="PhotoNavigation"
component={PhotoNavigation}
/>
</MainNavigation.Navigator>
</NavigationContainer>
);
};
MainNavigation 에는 2개의 스택을 가지고 있다. 1) TabNavigation 2)PhotoNavigation
여기서, 스택이라는 것은 카드라고 보면 된다. 1개의 화면에 여러 스택을 가지고 있기 때문에 필요 시 다른 카드를 꺼낼 수 있도록 되어 있다.
그리고 Container로 감싸주는 것은, 해당 네비게이션이 최상단에 위치해 있을 때 쓰인다. 따라서, 그 하위 네비게이션인
1) TabNavigation 2)PhotoNavigation 에는 사용하지 않는다.
해당 네비게이션의 첫번째 값이 TabNavigation 이기 때문에, TabNavigation이 실행 된다
>navigation/TabNavigation.js
import "react-native-gesture-handler";
import * as React from "react";
import { View } from "react-native";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import Home from "../screens/Home";
import Profile from "../screens/Profile";
import Search from "../screens/Search";
import Notifications from "../screens/Notifications";
const TabNavigation = createBottomTabNavigator();
export default () => {
return (
<TabNavigation.Navigator>
<TabNavigation.Screen name="Home" component={Home} />
<TabNavigation.Screen name="Profile" component={Profile} />
<TabNavigation.Screen
name="Add"
component={View}
listeners={({ navigation }) => ({
tabPress: (e) => {
e.preventDefault();
navigation.navigate("PhotoNavigation");
},
})}
/>
<TabNavigation.Screen name="Search" component={Search} />
<TabNavigation.Screen name="Notifications" component={Notifications} />
</TabNavigation.Navigator>
);
};
TabNavigation 은 createBottomTabNavigator을 사용한다. 해당 기능은 하단에 탭형식으로 각 컴포넌트를 보여줄 수 있다. 여기서 Add 탭을 누르면 PhotoNavigation이 실행되는데, 이것이 가능한 이유는, MainNavigation에서 이미 같은 카드 묶음으로 되어 있기 때문에 인자로 navigation을 받을 수 있기 때문이다. 그러면 PhotoNavigation을 봐보자.
>navigation/PhotoNavigation.js
import "react-native-gesture-handler";
import * as React from "react";
import { createMaterialTopTabNavigator } from "@react-navigation/material-top-tabs";
import { createStackNavigator } from "@react-navigation/stack";
import SelectPhoto from "../screens/Photo/SelectPhoto";
import TakePhoto from "../screens/Photo/TakePhoto";
import UploadPhoto from "../screens/Photo/UploadPhoto";
const Tab = createMaterialTopTabNavigator();
const Stack = createStackNavigator();
const PhotoTabs = () => {
return (
<Tab.Navigator tabBarPosition="bottom">
<Tab.Screen
name="SelectPhoto"
component={SelectPhoto}
options={{ tabBarLabel: "선택!" }}
/>
<Tab.Screen name="TakePhoto" component={TakePhoto} />
</Tab.Navigator>
);
};
export default () => {
return (
<Stack.Navigator headerMode="none">
<Stack.Screen name="PhotoTabs" component={PhotoTabs} />
<Stack.Screen name="UploadPhoto" component={UploadPhoto} />
</Stack.Navigator>
);
};
이부분을 잘봐보자. 여기서는 1) createMaterialTopTabNavigator 과 2) createStackNavigator이 모두 사용 된다.
일단 export되는 리턴값은 스택이 사용되고 첫번째 값은 TopTab이 사용 된다. 해당 PhotoTabs함수는 createMaterialTopTabNavigator로 만들어 진 것이며, 해당 기능은 상단에 좌우 스와이프 되는 탭기능을 만들게 된다. 이탭을 아래로 두기 위해 tabBarPosition="bottom" 를 선언 하였다. PhotoTabs에는2개의Screen이
존재 하고, 두 번째 Screen인 SelectPhoto 탭에서 text를 클릭하면 UploadPhoto 스택이 실행된다.
>screens/Photo/TakePhoto.js
import React from "react";
import { TouchableOpacity } from "react-native";
import styled from "styled-components";
const View = styled.View`
justify-content: center;
align-items: center;
flex: 1;
`;
const Text = styled.Text``;
export default ({ navigation }) => (
<View>
<TouchableOpacity onPress={() => navigation.navigate("UploadPhoto")}>
<Text>Take</Text>
</TouchableOpacity>
</View>
);
**스택 사용법 정리
스택이 여러개 쌓여있을때, 첫번째 스택이 첫 화면에 보여지는 것이고 두번째이상부터는 뒤에 있는 카드개념으로 호출되었을때 뒤에서 스윽 나오는식으로 구성되어야 한다.