어서와, 개발은 처음이지?

React Navigation으로 로그인, 탭 네비게이터 화면 구성하기 본문

React/React Native

React Navigation으로 로그인, 탭 네비게이터 화면 구성하기

오지고지리고알파고포켓몬고 2019. 8. 5. 14:48
반응형



(2020.07.09) 이 글은 react navigation v3, v4 환경에서 실행 확인한 글입니다.


이전에 react-native-navigation 사용법을 포스팅 한 적이 있는데, 

react-navigation이 react-native-navigation보다 설치도 간편하고, 사용하기 편리하고, 무엇보다 성능이 좋아져서 최근에 자주 사용하고 있습니다.


이번 글에서는 react-navigation을 사용하여 아래 구조를 구현해보겠습니다. (세부 기능 설명이 아닌 예제 위주로 작성하였습니다.)


- 시작화면(로그인) -> 메인화면(탭 네비게이터)로 이동

- 탭 네비게이터 내에서 화면 이동

- 탭 네비게이터에서 시작화면으로 이동



0. Repo


풀 코드는 Github에서 확인하실 수 있습니다.

- react navigation v3 적용 브랜치

- react navigation v4 적용 브랜치

- react navigation v5 적용 브랜치(작업중)

직접 실행해보시면 이해하기 좋으실 것 같습니다.


도움이 되셨다면 star를..




1. react-navigation 설치


react-navigation의 설치 방법은 공식 문서를 확인해주세요.

react native 0.60버전 이상/미만에 대한 설치 방법이 약간 상이하오니 주의해주세요.


(react-navigation 2.x를 사용하셔도 핵심 구조는 무관합니다)



2. 화면 구성

src
└── screens
    ├── HomeScreen
    ├── LoginScreen
    ├── SettingScreen
    ├── SomethingScreen
    └── index.js (AppContainer for react navigation)

예제 화면은 로그인, 홈, 세팅, 더미 화면 4가지로 구성하였습니다.



3. navigator 정의 (react navigation v3 기준)


navigator의 구조를 정의하는 코드인 screens/index.js를 살펴보겠습니다.


예제를 위한 구현이기 때문에 각 screen에 대한 자세한 코드는 생략하겠습니다.(Github 코드를 참고해주세요)

import React from 'react';
import {
    Text
} from 'react-native';
import { createStackNavigator, createBottomTabNavigator, createAppContainer } from 'react-navigation';

import LoginScreen from './LoginScreen';
import HomeScreen from './HomeScreen';
import SettingScreen from './SettingScreen';
import SomethingScreen from './SomethingScreen';

const HomeStack = createStackNavigator(
    {
        HomeScreen
    },
    {
        defaultNavigationOptions: ({navigation}) => ({
            title: 'Home',
        }),
    }
);
const SettingStack = createStackNavigator(
    {
        SettingScreen,
        SomethingScreen
    },
    {
        defaultNavigationOptions: ({navigation}) => ({
            title: 'Setting',
        }),
        initialRouteName: 'SettingScreen',
    }
);


const TabNavigator = createBottomTabNavigator(
    {
        Home: HomeStack,
        Setting: SettingStack,
    },
    {
        defaultNavigationOptions: ({navigation}) => ({
            tabBarIcon: ({focused, horizontal, tintColor}) => {
                const {routeName} = navigation.state;
                let icon = "▲";

                if(routeName === 'Home'){
                    icon = "🌈";
                } else if(routeName === 'Setting'){
                    icon = "🌙"
                } 

                // can use react-native-vector-icons
                // <Icon name={iconName} size={iconSize} color={iconColor} />
                return <Text style={{color: focused && "#46c3ad" || "#888"}}>{icon}</Text>
            }
        }),
        lazy: false,
        tabBarOptions: {
            activeTintColor: "#46c3ad",
            inactiveTintColor: "#888",
        },
    }
);

const AppStack = createStackNavigator(
    {
        LoginScreen: LoginScreen,
        TabNavigator: {
            screen: TabNavigator,
            navigationOptions: ({navigation}) => ({
                header: null,
            }),
        },
    }
);

export default createAppContainer(AppStack);


HomeScreen으로 구성된 Stack Navigator와, SettingScreen SomethingScreen으로 구성된 Stack Navigator를 사용하여 

Tab Navigator를 이루는 형태로 이루어져 있습니다.


(실질적으로 HomeScreen 내에서 화면 이동이 이루어지지 않는다면 HomeScreen을 Stack Navigator에 감싸지 않고 바로 사용하셔도 됩니다.)


이 Tab Navigator는 Stack Navigator에 한번 더 감싸집니다.

그리하여 LoginScreen -> Tab Navigator로 네비게이션이 되어 Home, Setting 화면으로 구성된 탭 화면을 사용할 수 있게 됩니다.


Setting 화면은 Setting, Something 화면으로 구성된 Stack Navigator이기 때문에, navigate 혹은 push 메소드를 사용하여 접근 할 수 있습니다.

export default class SettingScreen extends Component{
    _navigate(){
        this.props.navigation.navigate('SomethingScreen');
    }

    _logout(){ // 시작화면(LoginScreen)으로 이동
        const resetAction = StackActions.reset({
            index: 0,
            key: null,
            actions: [NavigationActions.navigate({ routeName: 'LoginScreen' })],
        });
        this.props.navigation.dispatch(resetAction);
    }

    render(){
        // ...
    }
}

Tab Navigator 내에서는 navigate 메소드로 상위 Stack Navigator의 초기 화면(LoginScreen)으로 이동되지 않기 때문에 navigator를 reset하는 방식으로 초기 화면으로 이동하도록 구현했습니다.



3-1. react navigation v4 변경사항


react navigation v4에서는 각 네비게이터가 분리되어 아래와 같은 형태로 나뉘어졌습니다.

import { createAppContainer } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import { createBottomTabNavigator } from "react-navigation-tabs";

// .. 이하 동일


위 예제에서 주요 구조 및 사용방법은 변화가 없지만 이렇게 세분화된 라이브러리로 관리되는 것을 확인하시고 공식 docs를 읽어보며 migrate하는 것을 추천드립니다.



3-2. react navigation v5


구조 및 사용성 측면으로 꽤 많은 부분이 변했습니다. 마치 react router dom을 사용하는것 처럼 네비게이터를 사용하는 모습을 볼 수 있습니다.

3-2 항목은 v5에 대한 변경사항 적용 후 다시 업데이트하겠습니다.



4. 그 외 몇 가지 (v3, v4)


- Tab Navigator에서 defaultNavigationOptions를 사용하여 Tab bar의 아이콘을 지정할 수 있습니다.

react-native-vector-icons등을 사용하여 더 예쁘게 구현할 수 있습니다.


- Stack Navigator에서 header: null 옵션을 설정하여 header bar를 제거할 수 있습니다.

플랫폼 별 동작이 조금 다를 수 있기 때문에 android, ios에서 동일한 액션을 제공하기 위해 header 컴포넌트를 직접 개발하여 사용하는 것도 나쁘지 않습니다.


- v5에서는 JSX를 사용한 옵션정의, 프로퍼티 명칭이 변경된 부분이 있는것같은데 확인 후 업데이트하겠습니다.






Comments