Tab Navigation은 화면 위에 쌓는 것이 아니라 선택된 버튼에 해당하는 화면으로 전환된다는 특징이 있다.

공식문서 : https://reactnavigation.org/docs/bottom-tab-navigator/

설치

$ /npm install @react-navigation/bottom-tabs

Tab Navigation 생성

생성된 Tab Navigation에는 Navigator 컴포넌트와 screen 컴포넌트를 이용해서 내비게이션과 화면을 구성한다.

createBottomTabNavigator를 이용해서 생성된 탭에는 Navigator과 Screen 컴포넌트가 있다.

// Tab Navigation 생성
const Tab = createBottomTabNavigator()

  <Tab.Navigator>
  	<Tab.Screen>
    </Tab.Screen>
  </Tab.Navigator>

실습

1. (실습 파일 생성)TabScreens.js 생성

import React from 'react';
import styled from 'styled-components/native';

const Container = styled.View`
    flex: 1;
    justify-content: center;
    align-items: center;
`;

const StyledText = styled.Text`
    font-size: 30px;
`;

export const Mail = () => {
    return (
        <Container>
            <StyledText>Mail</StyledText>
        </Container>
    );
};

export const Profile = () => {
    return (
        <Container>
            <StyledText>Profile</StyledText>
        </Container>
    );
};

export const Settings = () => {
    return (
        <Container>
            <StyledText>Setting</StyledText>
        </Container>
    );
};

2. index.js에 import 모아두기

//index.js
import Home from './Home';
import List from './List';
import Chat from './Chat';
import { Mail, Profile, Settings } from './TabScreens';

export { List, Chat, Home, Mail, Profile, Settings };

3. Navigation 폴더 아래 Tab.js파일 생성하여 탭 관리

  1. createBottomTabNavigator를 import 해오기
  2. 화면으로 사용할 컴포넌트들도 import해오기
  3. Tab Navigation에서도 Screen 컴포넌트에 컴포넌트로 설정된 컴포넌트에는 항상 navigationrouteprops로 전달된다.
import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Mail, Profile, Settings } from '../screens';

const Tab = createBottomTabNavigator();

const TabNav = () => {
    return (
        <Tab.Navigator>
            <Tab.Screen name='Mail' component={Mail} />
            <Tab.Screen name='Profile' component={Profile} />
            <Tab.Screen name='Settings' component={Settings} />
        </Tab.Navigator>
    );
};

export default TabNav;

4. Tab Navigation 사용

import { NavigationContainer } from '@react-navigation/native';
import React from 'react';
import TabNav from './Tab';

const Navigation = () => {
    return (
        <NavigationContainer>
            <TabNav />
        </NavigationContainer>
    );
};

export default Navigation;

App.js

import React from 'react';
import Navigation from './navigations';


export default function App() {
    return (
        <Navigation />
    );
}

잘 보인다.

5. Tab의 순서

Tab navigation에 첫번째로 보이는 화면은 Screen 컴포넌트의 순서이다. Tav 내비게이션을 사용할 떄 스크린 컴포넌트의 순서는 탭바의 버튼의 순서이기도 한다.

const TabNav = () => {
    return (
        <Tab.Navigator>
            <Tab.Screen name='Profile' component={Profile} />
            <Tab.Screen name='Mail' component={Mail} />
           <Tab.Screen name='Settings' component={Settings} />
        </Tab.Navigator>
    );
};

순서에 따라 달라지는 것을 볼 수 있다.

5-1. 화면 순서 고정 : initialRouteName

initialRouteName를 사용하면 버튼의 순서는 유지한 상태에서 첫번째 보이는 화면의 순서를 변경

const TabNav = () => {
    return (
        <Tab.Navigator initialRouteName='Mail'>
            <Tab.Screen name='Profile' component={Profile} />
            <Tab.Screen name='Settings' component={Settings} />
            <Tab.Screen name='Mail' component={Mail} />
        </Tab.Navigator>
    );
};

6. Tab icons 변경 : tabBarIcon

tabBarIcon에 들어오는 props를 확인해보면

            <Tab.Screen
                name='Mail'
                component={Mail}
                options={{
                    tabBarIcon: (props) => {
                        console.log(props);
                        return null;
                    },
                }}
            />

이런식으로 들어온다.

{"color": "#8E8E8F", "focused": false, "size": 25}
  • focused는 현재의 버튼이 선택되었는지 않되었는지 알려주는 값

tabBarIcon을 이용하여 Icon 변경

import { MaterialIcons } from '@expo/vector-icons';
(...)
<Tab.Screen
    name='Mail'
    component={Mail}
    options={{
        tabBarIcon: (props) => {
          return <MaterialIcons name='mail' size={props.size} color={props.color} />;
                    },
            }}
/>

아이콘 변경 함수를 만들어서 다른 아이콘도 적용

import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Mail, Profile, Settings } from '../screens';
import { MaterialIcons } from '@expo/vector-icons';

//아이콘 변경 함수
//파라미터로 name, size, color를 받고 아이콘을 이용해 컴포넌트를 반환
const TabIcon = ({ name, size, color }) => {
    return <MaterialIcons name={name} size={size} color={color} />;
};

const Tab = createBottomTabNavigator();

const TabNav = () => {
    return (
        <Tab.Navigator initialRouteName='Mail'>
            <Tab.Screen
                name='Profile'
                component={Profile}
                options={{
                    tabBarIcon: (props) => {
                        return TabIcon({ ...props, name: 'person' });
                    },
                }}
            />
            <Tab.Screen
                name='Settings'
                component={Settings}
                options={{
                    tabBarIcon: (props) => {
                        return TabIcon({ ...props, name: 'settings' });
                    },
                }}
            />
            <Tab.Screen
                name='Mail'
                component={Mail}
                options={{
                    tabBarIcon: (props) => {
                        return TabIcon({ ...props, name: 'mail' });
                    },
                }}
            />
        </Tab.Navigator>
    );
};

export default TabNav;

잘 변경된다.

7. Tab의 icon 라벨 수정 : 1. tarBarLabel 2. tabBarOptions

1. tarBarLabel

            <Tab.Screen
                name='Mail'
                component={Mail}
                options={{
                    tabBarIcon: (props) => {
                        return TabIcon({ ...props, name: 'mail' });
                    },
                    tabBarLabel: 'Inbox',
                }}
            />

tabBarLabel: ''이렇게 빈배열을 주기 되면 아래와 같이 빈 string이 렌더링 된다.

2. tabBarOptions

Navigator 컴포넌트의 tabBarOptions에서 showLabel를 설정하면 전체에서 라벨의 렌더링를 설정할 수 있다.

<Tab.Navigator initialRouteName='Mail' tabBarOptions={{ showLabel: false }}>

💥 트러블슈팅 :Bottom Tab Navigator: 'tabBarOptions' is deprecated. Migrate the options to 'screenOptions' instead.

위와 같은 경고문이 나온다. 해석해보자면 tabBarOptions는 없어졌으니 screenOptions으로 마이그레이션하라는 뜻이다. 공식문서를 찾아보니
공식문서 : https://reactnavigation.org/docs/upgrading-from-5.x/#the-tabbarvisible-option-is-no-longer-present
읽어보면 그 전에 tabBarOptions 안에 썼던 프로퍼티들 앞에 tabBar만 붙이면 사용가능하다.

그래서 screenOptions를 활용해서 아래와 같이 사용해 주었더니 잘 작동한다.

      <Tab.Navigator
            initialRouteName='Mail'
//`tabBarLabelPosition: 'beside-icon'`설정시 
            screenOptions={{ tabBarShowLabel: true, tabBarLabelPosition: 'beside-icon' }}
        >

참고로, tabBarLabelPosition: 'below-icon'로 설정시 라벨은 icon의 아래로 향한다.

8. TabBar 스타일 수정 : tabBarStyle

        <Tab.Navigator
            initialRouteName='Mail'
            screenOptions={{
                tabBarShowLabel: true,
                tabBarLabelPosition: 'below-icon',
                tabBarStyle: {
                    backgroundColor: 'gray',
                    borderTopColor: 'red',
                    borderTopWidth: 3,
                },
            }}
        >

9. TabBar의 icon 스타일 수정 : 1. tabBarActiveTintColor 2. tabBarInactiveTintColor

1. 버튼이 클릭되었을 때 icon 색상

tabBarActiveTintColor: '#ffffff',

2. 버튼이 클릭되지 않았을 때의 icon 색상

tabBarInactiveTintColor: '#333333',

10. icon 선택 여부에 따라 icon 변경 : focused

            <Tab.Screen
                name='Profile'
                component={Profile}
                options={{
                    tabBarIcon: (props) => {
                        return TabIcon({ ...props, name: props.focused ? 'person' : 'person-outline' });
                    },
                }}
            />

선택 전

선택 후

0개의 댓글