[React-native] React-native Navigation (stack, tab, drawer)

Chloe K·2023년 7월 3일
1

React-native

목록 보기
6/15
post-thumbnail
post-custom-banner

React Native Navigation

Stack + Drawer + Tab + MaterialTab + MaterialTopTab 사용하기


DrawerNavi
	ㄴ HomeStack
    	ㄴ HomeScreen
        ㄴ DetailScreen
    ㄴ ProfileStack
    	ㄴ ProfileScreen
        ㄴ NotificationScreen
    ㄴ TabNavi
    	ㄴTabFirstStackNavi
        	ㄴTabFirst
            ㄴModal
        ㄴTabSecond
    ㄴ MatertialTabStackNavi
    	ㄴTabFirstStackNavi
        	ㄴTabFirst
            ㄴModal
        ㄴTabSecond
    ㄴ MaterialTopTabStackNavi
    	ㄴTabFirstStackNavi
        	ㄴTabFirst
            ㄴModal
        ㄴTabSecond
    

*공부용으로 모든 네비게이터를 사용했음

Stack navigator

Home에서 Detail스크린으로 이동하는 HomeStack과 Profile에서 Notification 스크린으로 이동하는 ProfileStack 두개로 나눠서 스택 네비게이터를 만들었다.

import {createNativeStackNavigator} from '@react-navigation/native-stack';
import HomeScreen from './HomeScreen';
import ProfileScreen from './ProfileScreen';

const Stack = createNativeStackNavigator();


const HomeStack = () => {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={({navigation}) => ({
          // headerShown: false,
          title: 'Home',
          headerLeft: () => (
            <TouchableOpacity onPress={() => navigation.openDrawer()}>
              <Text>Drawer</Text>
            </TouchableOpacity>
          ),
        })}
      />
      <Stack.Screen
        name="Detail"
        component={Detail}
        options={{title: 'Detail'}}
      />
    </Stack.Navigator>
  );
};

const ProfileStack = ({navigation}) => {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Profile"
        component={ProfileScreen}
        options={{
          title: 'Profile',
          headerLeft: () => (
            <TouchableOpacity onPress={() => navigation.openDrawer()}>
              <Text>Drawer</Text>
            </TouchableOpacity>
          ),
        }}
      />
      <Stack.Screen
        name="Notification"
        component={Notification}
        options={{title: 'Notification'}}
      />
    </Stack.Navigator>
  );
};

// 📌 onPress={() => navigation.openDrawer()는 drawer 네이게이터를 만들 때 다룰 것이다.

Tab navigator

첫번째 탭에서는 모달을 사용하기 때문에 따로 TabFisrtStackNavi로 분리해 컴포넌트를 생성하고 탭 네비게이터에 넣었다.


TabFirstStackNavi
	ㄴTabFirst
    ㄴModal

TabNavi
	ㄴTabFirstStack
	ㄴTabSecond
const Tab = createBottomTabNavigator();

const TabFirstStackNavi = ({navigation}) => {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Tab First"
        component={TabFisrt}
        options={{headerShown: false}}
      />
      <Stack.Screen
        name="Modal"
        component={Modal}
        options={{
          presentation: 'modal',
          headerLeft: () => (
            <TouchableOpacity onPress={() => navigation.goBack()}>
              <Text>닫기</Text>
            </TouchableOpacity>
          ),
        }}
      />
    </Stack.Navigator>
  );
};

const TabNavi = () => {
  return (
    <Tab.Navigator
      initialRouteName="Home"
      screenOptions={{
        tabBarActiveTintColor: '#e91e63',
        tabBarLabelStyle: {fontSize: 12},
        tabBarStyle: {backgroundColor: 'powderblue'},
      }}>
      <Tab.Screen
        name="Home"
        component={TabFirstStackNavi}
        options={{tabBarLabel: 'Home'}}
      />
      <Tab.Screen
        name="Second"
        component={TabSecond}
        options={{tabBarLabel: 'Second'}}
      />
    </Tab.Navigator>
  );
};

Matertial Tab Navigator

Matertial Tab은 기본 Tab에서 애니메이션 효과를 추가한 네이게이터이다. 커스텀해서 사용할수도 있고 디폴트로 애니메이션 효과도 내장되어 있다.

// Matertial bottom tab (tab with animation)
const MatertialTab = createMaterialBottomTabNavigator();

const MatertialTabNavi = () => {
  return (
    <MatertialTab.Navigator initialRouteName="First">
      <MatertialTab.Screen name="First" component={TabFirstStackNavi} />
      <MatertialTab.Screen name="Second" component={TabSecond} />
    </MatertialTab.Navigator>
  );
};

Material Top Tab Navigator

const MaterialTobTab = createMaterialTopTabNavigator();

const MaterialTopTabNavi = () => {
  return (
    <MaterialTobTab.Navigator>
      <MaterialTobTab.Screen
        name="Home"
        component={TabFirstStackNavi}
        options={{headerShown: false}}
      />
      <MaterialTobTab.Screen
        name="Second"
        component={TabSecond}
        options={{headerShown: false}}
      />
    </MaterialTobTab.Navigator>
  );
};

// 📌 material tab 네이게이션은 헤더를 지원하지 않는다. -> 헤더를 사용하려면 stack navigator로 감싸줘야한다.
// 📌 matertial top navigation에 헤더를 넣어주기 위해 stack에 넣어준다. 
// 위 캡쳐샷과 같이 MaterialTopTabNavi라는 헤더가 생성된다.
const MaterialTopTabStackNavi = ({navigation}) => {
  return (
    <Stack.Navigator
      screenOptions={{
        headerLeft: props => (
          <TouchableOpacity onPress={() => navigation.openDrawer()}>
            <Text>Drawer</Text>
          </TouchableOpacity>
        ),
      }}>
      <Stack.Screen name="MaterialTopTabNavi" component={MaterialTopTabNavi} />
    </Stack.Navigator>
  );
};

Drawer Navigator

드로어를 전역에서 사용하기 위해서 default로 export 한다.
커스텀해서 사용하고 싶다면 커스텀 드로어 컴포넌트를 만들고 드로어 네비게이터에 props전달해서 커스텀 컴포넌트를 리턴하면 된다.

const DrawerNavi = ({navigation}) => {
  return (
    <Drawer.Navigator
      initialRouteName="Notes"
      // drawerContent={props => <CustomDrawerContent {...props} />}
      screenOptions={{
        headerShown: false,
        drawerActiveTintColor: 'red',
        drawerActiveBackgroundColor: 'steelblue',
        drawerInactiveTintColor: 'black',
      }}>
      <Drawer.Screen
        name="Notes"
        component={HomeStack}
        options={{
          drawerLabel: 'HOME',
        }}
      />
      <Drawer.Screen
        name="User"
        component={ProfileStack}
        options={{drawerLabel: 'PROFILE'}}
      />

      <Drawer.Screen name="TabNavi" component={TabNavi} />
      <Drawer.Screen
        name="MatertialTabStackNavi"
        component={MatertialTabStackNavi}
      />
      {/* <Drawer.Screen name="MaterialTopTabNavi" component={MaterialTopTabNavi} /> */}
      <Drawer.Screen
        name="MaterialTopTabStackNavi"
        component={MaterialTopTabStackNavi}
      />
    </Drawer.Navigator>
  );
};


// 커스텀 드로어
const CustomDrawerContent = props => {
  return (
    <DrawerContentScrollView {...props} style={{backgroundColor: 'gold'}}>
      <DrawerItemList {...props} />
      <DrawerItem
        label="Home"
        inactiveBackgroundColor="gold"
   		activeBackgroundColor="steelblue"
        activeTintColor="white"
        onPress={() => props.navigation.navigate('Home')}
      />
      <DrawerItem
        label="Profile"
        onPress={() => props.navigation.navigate('User', {screen: 'Profile'})}
      />
    </DrawerContentScrollView>
  );
};

export default DrawerNavi;

App.js

function App() {
  return (
    <NavigationContainer>
      <DrawerNavi />
    </NavigationContainer>
  );
}

export default App;
profile
Frontend Developer
post-custom-banner

0개의 댓글