๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“ฑ Cross Platform/React Native

[React Native] Bottom-Tab ๋งŒ๋“ค์–ด ํ™”๋ฉด ์ด๋™ํ•˜๊ธฐ (Bottom-tab-navigator)

by Fomagran ๐Ÿ’ป 2022. 6. 16.
728x90
๋ฐ˜์‘ํ˜•

 

์•ˆ๋…•ํ•˜์„ธ์š” Foma ์ž…๋‹ˆ๋‹ค!

 

์ด๋ฒˆ์—” ์ €๋ฒˆ Navigation์„ ์ด์šฉํ•˜์—ฌ ์Šคํฌ๋ฆฐ ์ด๋™ํ•˜๊ธฐ ๊ธ€์— ์ด์–ด์„œ Bottom-tab์„ ๋งŒ๋“ค์–ด ํ™”๋ฉด์„ ์ด๋™ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

(ํ•ด๋‹น ์ฝ”๋“œ ๊ธฐ๋ฐ˜์œผ๋กœ ์ง„ํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ˜น์‹œ ์•ˆ๋ณด์‹  ๋ถ„๋“ค์€ ๋ณด๊ณ  ์™€์ฃผ์„ธ์š”!)

 

๋ฐ”๋กœ ์‹œ์ž‘ํ• ๊ฒŒ์š”~

 

์–ธ์–ด๋Š” TypeScript, ํ™˜๊ฒฝ์€ Expo๋กœ ์ง„ํ–‰ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!


Install

 

Bottom-tabs

 

npm install @react-navigation/bottom-tabs

 

 

Vector-icons

 

npm install @expo/vector-icons

 


index.tsx

 

import

 

๋ฐ”ํ…€ ํƒญ์„ ๋งŒ๋“œ๋Š”๋ฐ ํ•„์š”ํ•œ ๋ชจ๋“ˆ์„ import ํ•ด์ค๋‹ˆ๋‹ค.

 

import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { NavigationContainer } from "@react-navigation/native";
import { FontAwesome, Entypo } from "@expo/vector-icons";

import ScreenA from "../screens/ScreenA";
import ScreenB from "../screens/ScreenB";

 

Navigation Container

 

 

Navigation Container ์•ˆ์— ์‹œ์ž‘์ด ๋  ๋„ค์ด๊ฒŒ์ดํ„ฐ์ธ Root Navigator๋ฅผ ๋„ฃ์–ด ์ค๋‹ˆ๋‹ค.

 

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

 

Root Navigator

 

Stack Navigator๋ฅผ ์ƒ์„ฑํ•ด ์ค€ ๋’ค Stack ์•ˆ์— Root๊ฐ€ ๋  ํ™”๋ฉด์ธ BottomTabNavigator๋ฅผ ๋„ฃ์–ด ์ค๋‹ˆ๋‹ค.

 

const Stack = createNativeStackNavigator();
function RootNavigator() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Root" component={BottomTabNavigator} />
    </Stack.Navigator>
  );
}

 

Bottom Tab Navigator

 

Bottom Tab Navigator๋ฅผ ์ƒ์„ฑํ•ด ์ฃผ๊ณ  ์ดˆ๊ธฐ ํ™”๋ฉด(initialRouteName)์„ Screen A๋กœ ์ง€์ •ํ•ด ์ค๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ๋ฐ”ํ…€ ํƒญ์— Screen A, Screen B ํ™”๋ฉด์„ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

 

const BottomTab = createBottomTabNavigator();
function BottomTabNavigator() {
  return (
    <BottomTab.Navigator initialRouteName="ScreenA">
      <BottomTab.Screen name="ScreenA" component={ScreenA} />
      <BottomTab.Screen name="ScreenB" component={ScreenB} />
    </BottomTab.Navigator>
  );
}

Test

 

์œ„๊นŒ์ง€ ์ง„ํ–‰ํ•œ ๋’ค ํ™”๋ฉด์„ ํ™•์ธํ•˜๋ฉด ๋ฐ”ํ…€ ํƒญ์— ์žˆ๋Š” Screen A, Screen B ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๊ฐ ํ™”๋ฉด์œผ๋กœ ์ด๋™๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 


Hide Root Header

 

ํ™”๋ฉด์„ ๋ณด๋ฉด Root ํ—ค๋”์™€, ๊ฐ ํ™”๋ฉด์˜ ํ—ค๋”๊ฐ€ ๊ฒน์น˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Root ํ—ค๋”๋ฅผ ์ˆจ๊ธฐ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

index.tsx์—์„œ RootNavigator์—์„œ Root ํ™”๋ฉด์˜ options์— headerShown์„ false๋กœ ํ•ด์ค๋‹ˆ๋‹ค.

 

function RootNavigator() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Root"
        component={BottomTabNavigator}
        options={{ headerShown: false }}
      />
    </Stack.Navigator>
  );
}

 

์•„๋ž˜์™€ ๊ฐ™์ด ํ•ด๋‹น ์Šคํฌ๋ฆฐ์˜ ํ—ค๋”๋งŒ ๋ณด์ด๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 


Icon

 

์œ„ ํ™”๋ฉด์—์„œ ๋ณด๋ฉด ํ•ด๋‹น ๋ฐ”ํ…€ ํƒญ ๋„ค๋น„๊ฒŒ์ดํ„ฐ์˜ ์•„์ด์ฝ˜์ด ์ด์ƒํ•œ ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์œ„์—์„œ ๋ฏธ๋ฆฌ vector-icon ๋ชจ๋“ˆ์„ ์„ค์น˜ ํ–ˆ๋Š”๋ฐ์š”.

 

ํ•ด๋‹น FontAwesome์„ ์ด์šฉํ•˜์—ฌ BottomTab์˜ Screen์˜ options์˜ tabBarIcon์˜ ์ด๋ฆ„, ์‚ฌ์ด์ฆˆ, ์ปฌ๋Ÿฌ ๋“ฑ์„ ์ง€์ •ํ•ด ์ค๋‹ˆ๋‹ค.

 

function BottomTabNavigator() {
  return (
    <BottomTab.Navigator initialRouteName="ScreenA">
      <BottomTab.Screen
        name="ScreenA"
        component={ScreenA}
        options={{
          tabBarIcon: () => (
            <FontAwesome name="home" size={24} color={"black"} />
          ),
        }}
      />
      <BottomTab.Screen
        name="ScreenB"
        component={ScreenB}
        options={{
          tabBarIcon: () => (
            <Entypo name="add-to-list" size={24} color={"black"} />
          ),
        }}
      />
    </BottomTab.Navigator>
  );

 

์•„๋ž˜์™€ ๊ฐ™์ด ์ง€์ •ํ•ด ์ค€ ์‚ฌ์ด์ฆˆ ์ปฌ๋Ÿฌ ์ด๋ฆ„๋Œ€๋กœ ์•„์ด์ฝ˜์ด ๋ณด์ด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

 

 

 

์ง์ ‘ ์ง€์ •ํ•ด ์ค„ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๋งŒ์•ฝ ๊ธฐ๋ณธ ๊ฐ’์œผ๋กœ ์„ธํŒ…ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด tabBarIcon์— ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๊ธฐ๋ณธ์œผ๋กœ ์ง€์ •ํ•  ํ”„๋กœํผํ‹ฐ๋ฅผ ์ž…๋ ฅํ•ด ์ค๋‹ˆ๋‹ค.

 

 <BottomTab.Navigator initialRouteName="ScreenA">
      <BottomTab.Screen
        name="ScreenA"
        component={ScreenA}
        options={{
          tabBarIcon: ({ color, size }) => (
            <FontAwesome name="home" size={size} color={color} />
          ),
        }}
      />
      <BottomTab.Screen
        name="ScreenB"
        component={ScreenB}
        options={{
          tabBarIcon: ({ color, size }) => (
            <Entypo name="add-to-list" size={size} color={color} />
          ),
        }}
      />

 

์•„๋ž˜์™€ ๊ฐ™์ด ๊ธฐ๋ณธ์œผ๋กœ ์„ธํŒ…๋œ ์ƒ‰,์‚ฌ์ด์ฆˆ๊ฐ€ ์ง€์ •๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€