김마드 2020. 5. 4. 13:20

#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>
);

 

**스택 사용법 정리

스택이 여러개 쌓여있을때, 첫번째 스택이 첫 화면에 보여지는 것이고 두번째이상부터는 뒤에 있는 카드개념으로 호출되었을때 뒤에서 스윽 나오는식으로 구성되어야 한다.