2022. 1. 19. 19:55ㆍReact Native/Basic

11. [Drawer] Custom Component
side drawer를 customize 하는 방법에 대해서 알아보자!
CustomDrawerContent를 대체하는 SideDrawer를 만들어보자
sideDrawer를 만든 뒤에 스타일까지 지정하면 스크린 간 이동을 하도록 설정을 추가로 해줘야 한다. 이건 onPress를 해서 이동하는 함수를 사용해주면 된다. 이동하는 함수는 새로 만들어 준다.
navigateToScreen = (route) => () => {
this.props.navigation.dispatch(
CommonActions.navigate({
name: route,
params: {},
}),
);
};
route 는 화면 이동을 위해서 파라미터로 받아온 것인데 여기서 arrow function이 2번 쓰인 이유는 뭘까?
arrow 가 2개니까 리턴값이 2개라고 생각하면 되는데 중괄호 안의 값을 리턴하는 함수를 또 리턴값으로 받는 것이다. 그때의 파라미터로 route가 들어가는 것이다. 중괄호 안에 구현할 내용이 state를 업데이트 하는 내용이고, redux에서 배울 텐데 여기서 리턴을 1번만 하게 되면 업데이트가 무한루프에 걸리게 된다. 그래서 함수가 시작할 때 업데이트 behavior를 끊어주기 위한 트리거 장치가 필요하게 되고 그래서 arrow를 2번 쓴 것이다.
CommonActions라는 라이브러리는 여러 actions creators를 쓰게 도와주는데 그 중 하나가 navigate라는 액션이다. 특정 route에 이동하게끔 도와주는 액션이다. 이런 액션이 발생하면 dispatch를 통해서 state 값을 업데이트 시켜준다.
side drawer를 통해 터치된 route로 이동시키고 그 때 params를 업데이트 시키라는 코드이다.
home_drawer.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow strict-local
*/
import React, {Component} from 'react';
import {StyleSheet, Text, View, Button} from 'react-native';
class DrawerHomeScreen extends Component {
render() {
return (
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text>Home Screen</Text>
<Button
title="To User Screen"
onPress={() => {
this.props.navigation.navigate('User');
}}
/>
</View>
);
}
}
const styles = StyleSheet.create({});
export default DrawerHomeScreen;
user_drawer.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow strict-local
*/
import React, {Component} from 'react';
import {StyleSheet, Text, View, Button, Image} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import Logo from './assets/pics/home_icon.png';
class DrawerUserScreen extends Component {
drawerStyle = () => {
this.props.navigation.setOptions({
drawerIcon: () => {
<Image source={Logo} style={{width: 40, height: 40}} />;
},
});
};
render() {
this.drawerStyle();
return (
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text>User Screen</Text>
</View>
);
}
}
const styles = StyleSheet.create({});
export default DrawerUserScreen;
my_drawer.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow strict-local
*/
import React, {Component} from 'react';
import {StyleSheet, Text, View, Button, Image} from 'react-native';
import {ScrollView} from 'react-native-gesture-handler';
import Logo from './assets/pics/home_icon.png';
import {CommonActions} from '@react-navigation/native';
class SideDrawer extends Component {
navigateToScreen = route => () => {
this.props.navigation.dispatch(
CommonActions.navigate({
name: route,
params: {},
}),
);
};
render() {
return (
<View style={styles.container}>
<ScrollView>
<View>
<View style={styles.imageContainer}>
<Image source={Logo} style={{width: 40, height: 40}} />
</View>
<Text style={styles.sectionHeading}>Section 1</Text>
<View style={styles.navSectionStyle}>
<Text
style={styles.navItemStyle}
onPress={this.navigateToScreen('Home')}>
Home
</Text>
<Text
style={styles.navItemStyle}
onPress={this.navigateToScreen('User')}>
User
</Text>
<Text
style={styles.navItemStyle}
onPress={() => {
alert('Help Window');
}}>
Help
</Text>
<Text
style={styles.navItemStyle}
onPress={() => {
alert('Info Window');
}}>
Info
</Text>
</View>
</View>
</ScrollView>
<View style={{paddingLeft: 10, paddingBottom: 30}}>
<Text>Copyright @ byein, 2022.</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 80,
},
imageContainer: {
alignItems: 'center',
padding: 50,
},
sectionHeading: {
color: '#fff',
background: '#ef9de4',
paddingVertical: 10,
paddingHorizontal: 15,
fontWeight: 'bold',
},
navSectionStyle: {
backgroundColor: '#04b6ff',
},
navItemStyle: {
padding: 10,
color: '#fff',
},
});
export default SideDrawer;
App.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow strict-local
*/
import React, {Component} from 'react';
import {StyleSheet, Text, View, Image, Button, Linking} from 'react-native';
import {DrawerActions, NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {
createDrawerNavigator,
DrawerContentScrollView,
DrawerItem,
DrawerItemList,
} from '@react-navigation/drawer';
import HomeScreen from './src/home';
import UserScreen from './src/user';
import LogoTitle from './src/logo';
import DrawerHomeScreen from './src/home_drawer';
import DrawerUserScreen from './src/user_drawer';
import PictogramHome from './src/assets/pics/home_icon.png';
import SideDrawer from './src/my_drawer';
const Stack = createNativeStackNavigator();
const Drawer = createDrawerNavigator();
// CustomDrawerContent = props => {
// return (
// <DrawerContentScrollView {...props}>
// <DrawerItemList {...props} />
// <DrawerItem
// label="Help"
// onPress={() => Linking.openURL('http://www.google.com')}
// icon={() => <LogoTitle />}
// />
// <DrawerItem label="Info" onPress={() => alert('Info window')} />
// </DrawerContentScrollView>
// );
// };
class App extends Component {
// logoTitle = () => {
// return (
// <Image
// style={{width: 40, height: 40}}
// source={require('./src/assets/pics/home_icon.png')}
// />
// );
// };
render() {
return (
<NavigationContainer>
<Drawer.Navigator
initialRouteName="Home"
screenOptions={{
drawerType: 'front',
drawerPosition: 'right',
drawerStyle: {
backgroundColor: '#c6cbef',
width: 200,
},
drawerActiveTintColor: 'red',
drawerActiveBackgroundColor: 'skyblue',
}}
drawerContent={props => <SideDrawer {...props} />}>
<Drawer.Screen
name="Home"
component={DrawerHomeScreen}
options={{
drawerIcon: () => {
<Image
source={PictogramHome}
style={{width: 40, height: 40}}
/>;
},
}}
/>
<Drawer.Screen name="User" component={DrawerUserScreen} />
</Drawer.Navigator>
</NavigationContainer>
// <NavigationContainer>
// <Stack.Navigator
// initialRouteName="Home"
// screenOptions={{
// headerStyle: {
// backgroundColor: '#a4511e',
// },
// headerTintColor: '#ffffff',
// headerTitleStyle: {
// fontWeight: 'bold',
// color: '#f3d612',
// },
// }}>
// <Stack.Screen
// name="Home"
// component={HomeScreen}
// options={{
// title: 'Home Screen',
// headerTitle: () => <this.logoTitle />,
// headerRight: () => (
// <Button
// title="info"
// onPress={() => alert('I am a button!!')}
// color="orange"
// />
// ),
// }}
// />
// <Stack.Screen
// name="User"
// component={UserScreen}
// initialParams={{
// userIdx: 50,
// userName: 'Gildong',
// userLastName: 'Go',
// }}
// options={{
// title: 'User Screen',
// headerStyle: {
// backgroundColor: 'pink',
// },
// headerTintColor: 'red',
// headerTitleStyle: {
// fontWeight: 'bold',
// color: 'purple',
// },
// }}
// />
// </Stack.Navigator>
// </NavigationContainer>
);
}
}
const styles = StyleSheet.create({});
export default App;
참고 자료
iOS/Android 앱 개발을 위한 실전 React Native - Basic - 인프런 | 강의
Mobile App Front-End 개발을 위한 React Native의 기초 지식 습득을 목표로 하고 있습니다. 진입장벽이 낮은 언어/API의 활용을 통해 비전문가도 쉽게 Native Mobile App을 개발할 수 있도록 제작된 강의입니다
www.inflearn.com
'React Native > Basic' 카테고리의 다른 글
[React Native] React Navigation - 13. [Tab] Style 설정 (0) | 2022.01.19 |
---|---|
[React Native] React Navigation - 12. [Tab] 설치 및 화면 Linking (0) | 2022.01.19 |
[React Native] React Navigation - 10. [Drawer] Style 설정 (0) | 2022.01.19 |
[React Native] React Navigation - 9. [Drawer] 설치 및 화면 Linking (0) | 2022.01.19 |
[React Native] React Navigation - 8. [Stack] Header Bar에 버튼 추가 (0) | 2022.01.17 |