프로그래밍/React Native

react navigation v5 drawer 추가하기

p-a-r-k 2021. 1. 21. 16:02
반응형

react-navigation에서 제공하는 기능으로 drawer를 추가할 수 있다.

@react-navigation/drawer 를 인스톨 해준다.

npm install @react-navigation/drawer

 

기본적인 코드는 아래와 같다.

import { createDrawerNavigator } from '@react-navigation/drawer';

const Drawer = createDrawerNavigator();

function MyDrawer() {
  return (
    <Drawer.Navigator>
      <Drawer.Screen name="Feed" component={Feed} />
      <Drawer.Screen name="Article" component={Article} />
    </Drawer.Navigator>
  );
}

Navigator를 반환하는 함수를 하나만들면 되는데,

Drawer Navigator는 헤더가 없는게 특징이다.

직접 header 컴포넌트를 만들어서 넣어주면된다.

 

커스텀한 메뉴를 추가하거나, 스타일을 주고싶은 경우가 있다.

drawerContent props로 상위 props를 받아주는 커스텀 컴포넌트를 넘겨주면된다.

import {
    createDrawerNavigator,
    DrawerContentScrollView,
    DrawerItemList,
    DrawerItem
} from '@react-navigation/drawer';

const CustomDrawerContent = (props) => {
    // 로그아웃
    const doLogout = () => {
        console.log("logout");
    };

    return (
        <DrawerContentScrollView {...props}>
            <DrawerItemList {...props}/>
            <DrawerItem
                label="로그아웃"
                onPress={doLogout}
            />
        </DrawerContentScrollView>
    )
};

function DrawerScreen () {
    return (
        <Drawer.Navigator
            initialRouteName="home"
            drawerType="front"
            drawerPostion="right"
            drawerContentOptions={{
                // activeTintColor: 'blue',
                // activeBackgroundColor: 'yellow'
            }}
            drawerStyle={{
                // backgroundColor:'#c6cbef',
                // width:200
            }}
            drawerContent={ props => <CustomDrawerContent {...props} /> }
        >
            <Drawer.Screen name="Home"
                          component={HomeScreen}
                           options={{ drawerLabel: '메인' }}/>

            <Drawer.Screen name="Bluetooth"
                          component={BluetoothScreen}
                           options={{ drawerLabel: '프린터 연결 설정' }}/>
        </Drawer.Navigator>
    )
}

Drawer.Navigator 속성들을 먼저 보면,

drawerType이 있다.

  1. slide > side-bar가 튀어나온만큼 뒤쪽이 밀려나간다.
  2. front > 뒤 화면이 고정되고 위에 오버레이해서 덮는다.
  3. permanent > side-bar가 열려서 닫히지 않으며, 뒤에가 밀린다. 큰 화면 경우 고정하고 싶을 떄 사용.

drawerPosition은 bar가 열릴 위치이다. left와 right가 있다.

그외, drawerStyledrawerContentOptions로 스타일을 줄 수가 있다.

 

DrawerContentScrollView로 감싸진 컴포넌트내에 

DrawerItemList는 기본적으로 Navigator속에 정의된 스크린들이 나열되고,

추가로 넣고싶은경우 DrawerItem을 이용하여 나타낼 수 있다.

위 경우에는 `로그아웃` 버튼을 추가로 넣어보았다.

 

또한, Drawer.Screen으로 정의한 화면들의 메뉴명이 name값인 영어로 나오는것은,

options props의 drawerLabel 속성으로 지정해주면 메뉴명이 해당 명칭으로 표시된다.

 

Drawer Screen 컴포넌트 내부에서는 Header를 구현하여 `메뉴` 버튼을 누르면 side-bar를 열어주면된다.

아래는 react-native-element 라이브러리의 Button과 Header를 사용하였다.

import {CommonActions, DrawerActions} from '@react-navigation/native';
import {Button, Header} from "react-native-elements";

<Header
    ViewComponent={/* view 컴포넌트 구현 */}
    leftComponent={
        <Button
            type="clear"
            onPress={() => {
                navigation.dispatch(DrawerActions.openDrawer());
            }}
            icon={{
                name: 'bars',
                type: 'font-awesome',
                color: '#fff'
            }}>
        </Button>
    }
    centerComponent={{
        text: `${user.me?.username}님 안녕하세요`,
        style: {
            fontSize: 18,
            fontWeight: 'bold',
            color: '#fff'
        }
    }}
    containerStyle={{
        backgroundColor: '#333',
    }}
    statusBarTranslucent={true}
/>

메뉴오픈 시 navigation.dispatch(DrawerActions.openDrawer()); 를 호출한다.

물론, 화면 왼쪽에서 오른쪽으로 제스처를 시도해도 열린다.

open drawer

side-bar에 아이콘을 넣고싶은 경우도 있다. 여러방법이 있는데,

 

1. Drawer Navigator 정의시 작성.

<Drawer.Screen
    name="iconScreen"
    component={/* user screen */}
    options={{
        drawerIcon:() => (
            <Image
                source={/* user path */}
                style={{width: 30, height: 30}}
            />
        )
    }}
/>

2. Custom Drawer 구현시 작성.

<DrawerContentScrollView {...props}>
    <DrawerItemList {...props}/>
    <DrawerItem
        label="로그아웃"
        onPress={doLogout}
    />
    <DrawerItem
        label="아이콘이 있는 메뉴"
        onPress={() => alert("hello")}
        icon={() => <YourIcon/>}
    />
</DrawerContentScrollView>

3. Screen Mount시에 setOptions.

useEffect(() => {
    props.navigation.setOptions({
        drawerIcon:() => <YourIcon/>
    });
    return () => {}
}, []);
반응형