Skip to content
coooldoggy.dev

React Native - Components

React, ReactNative, TIL2 min read

React Native Components

React Native에서 사용하는 컴포넌트들에 대한 설명을 정리한다.

공식문서 에서 자세한 설명이나 빠진 부분을 찾아볼 수 있다.

Button

1<View style={styles.container}>
2 <Button
3 onPress={() => {
4 Alert.alert('Pressed!!');
5 }}
6 title='Button'
7 color='#841584'
8 accessibilityLabel='You can click this one to show alert press.'
9 />
10 </View>
  • onPress : Onclick event 를 정의함
  • Title: Button에 나타낼 text를 정의함
  • accessibilityLabel : 시각장애인용 텍스트 대치어를 정의함
  • color : IOS에서는 text 색, AOS에서는 button의 배경색을 정의함
  • Disabled: true 이면 버튼이 비활성화 됨

Activity Indicator

1<View style={styles.container}>
2 <View
3 style={{
4 marginTop: 40,
5 justifyContent: 'center',
6 }}
7 >
8 <ActivityIndicator
9 size="large" color="#0000ff"
10 />
11 </View>
12 <View
13 style={{
14 marginTop: 40,
15 justifyContent: 'center',
16 }}
17 >
18 <ActivityIndicator
19 size="small"
20 color="black"
21 />
22 </View>
23 <View
24 style={{
25 marginTop: 40,
26 justifyContent: 'center',
27 }}
28 >
29 <ActivityIndicator
30 animating={false}
31 size="large"
32 color="black"
33 hidesWhenStopped={false}
34 />
35 </View>
36 {/* <View
37 style={{
38 marginTop: 40,
39 justifyContent: 'center',
40 }}
41 >
42 <ActivityIndicator
43 size={'40'}
44 color='#3d3d3d'
45 />
46 </View> */}
47 </View>
  • Animating : 인디케이터를 보여줄지 말지 (true/false)
  • Color: spinner 색을 결정함 IOS 기본색은 회색, AOS 기본색은 다크시안
  • hidesWhenStopped : animated 되지 않았을때 자동으로 숨길지 여부를 설정
  • Size: 인디케이터의 사이즈를 결정한다.

DatePicker - IOS

시간, 날짜를 선택하는 피커화면을 만든다. onDateChange 콜백함수와 연동하여 사용한다.

1import React, {Component} from 'react';
2import {DatePickerIOS, View, StyleSheet} from 'react-native';
3
4export default class App extends Component {
5 constructor(props) {
6 super(props);
7 this.state = {chosenDate: new Date()};
8
9 this.setDate = this.setDate.bind(this);
10 }
11
12 setDate(newDate) {
13 this.setState({chosenDate: newDate});
14 }
15
16 render() {
17 return (
18 <View style={styles.container}>
19 <DatePickerIOS
20 date={this.state.chosenDate}
21 onDateChange={this.setDate}
22 />
23 </View>
24 );
25 }
26}
27
28const styles = StyleSheet.create({
29 container: {
30 flex: 1,
31 justifyContent: 'center',
32 },
33});
  • Date: 선택된 날짜를 반환한다.
  • onChange: 날짜나 시간이 바뀌었을 때 호출하는 함수
  • onDateChange: 날짜가 바뀌었을 떄 호출하는 함수
  • MaximunDate/ minimunDate : 날짜 선택의 최대/ 최소 범위를 설정한다.
  • minuteInterval : 시간선택의 분단위를 설정한다.
  • mode : 피커의 모드를 선택한다. date, time, datetime, countdown
  • Locale : 피커의 날짜, 시간의 지역을 설정한다.
  • initialDate : 사용자가 날짜를 선택하기 전의 기본 값을 설정한다.

DrawerLayout - Android

안드로이드의 DrawerLayout을 만들 때 사용한다.

1render: function() {
2 var navigationView = (
3 <View style={{flex: 1, backgroundColor: '#fff'}}>
4 <Text style={{margin: 10, fontSize: 15, textAlign: 'left'}}>I'm in the Drawer!</Text>
5 </View>
6 );
7 return (
8 <DrawerLayoutAndroid
9 drawerWidth={300}
10 drawerPosition={DrawerLayoutAndroid.positions.Left}
11 renderNavigationView={() => navigationView}>
12 <View style={{flex: 1, alignItems: 'center'}}>
13 <Text style={{margin: 10, fontSize: 15, textAlign: 'right'}}>Hello</Text>
14 <Text style={{margin: 10, fontSize: 15, textAlign: 'right'}}>World!</Text>
15 </View>
16 </DrawerLayoutAndroid>
17 );
18},
  • onDrawerClose : 레이아웃이 닫힐때 호출하는 함수를 정의한다.
  • drawerPosition : 레이아웃의 방향을 결정한다. DrawerConsts.DrawerPosition.Left/ DrawerConsts.DrawerPosition.Right
  • keyboardDismissMode: 드래그시 키보드를 숨길지 여부를 설정한다. None: 숨기지않음/ on-drag : 드래그가 시작되면 숨김
  • onDrawerOpen: 레이아웃이 열릴때 호출하는 함수를 정의한다.
  • onDrawerStateChange: 레이아웃의 상태가 변할때 호출하는 함수를 정의한다.

Flat List

기본적인 리스트뷰를 만들어준다. Section 별로 분류되는 기능은 SectionList를 이용한다.

가로, 세로 뷰를 지원하며, 헤더와 푸터, 당겨서 새로고침, 스크롤시 로드 등을 기본으로 지원한다.

1import React from 'react';
2import { SafeAreaView, View, FlatList, StyleSheet, Text } from 'react-native';
3import Constants from 'expo-constants';
4
5const DATA = [
6 {
7 id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
8 title: 'First Item',
9 },
10 {
11 id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
12 title: 'Second Item',
13 },
14 {
15 id: '58694a0f-3da1-471f-bd96-145571e29d72',
16 title: 'Third Item',
17 },
18];
19
20function Item({ title }) {
21 return (
22 <View style={styles.item}>
23 <Text style={styles.title}>{title}</Text>
24 </View>
25 );
26}
27
28export default function App() {
29 return (
30 <SafeAreaView style={styles.container}>
31 <FlatList
32 data={DATA}
33 renderItem={({ item }) => <Item title={item.title} />}
34 keyExtractor={item => item.id}
35 />
36 </SafeAreaView>
37 );
38}
39
40const styles = StyleSheet.create({
41 container: {
42 flex: 1,
43 marginTop: Constants.statusBarHeight,
44 },
45 item: {
46 backgroundColor: '#f9c2ff',
47 padding: 20,
48 marginVertical: 8,
49 marginHorizontal: 16,
50 },
51 title: {
52 fontSize: 32,
53 },
54});

선택기능을 추가한 리스트

1import React from 'react';
2import {
3 SafeAreaView,
4 TouchableOpacity,
5 FlatList,
6 StyleSheet,
7 Text,
8} from 'react-native';
9import Constants from 'expo-constants';
10
11const DATA = [
12 {
13 id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
14 title: 'First Item',
15 },
16 {
17 id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
18 title: 'Second Item',
19 },
20 {
21 id: '58694a0f-3da1-471f-bd96-145571e29d72',
22 title: 'Third Item',
23 },
24];
25
26function Item({ id, title, selected, onSelect }) {
27 return (
28 <TouchableOpacity
29 onPress={() => onSelect(id)}
30 style={[
31 styles.item,
32 { backgroundColor: selected ? '#6e3b6e' : '#f9c2ff' },
33 ]}
34 >
35 <Text style={styles.title}>{title}</Text>
36 </TouchableOpacity>
37 );
38}
39
40export default function App() {
41 const [selected, setSelected] = React.useState(new Map());
42
43 const onSelect = React.useCallback(
44 id => {
45 const newSelected = new Map(selected);
46 newSelected.set(id, !selected.get(id));
47
48 setSelected(newSelected);
49 },
50 [selected],
51 );
52
53 return (
54 <SafeAreaView style={styles.container}>
55 <FlatList
56 data={DATA}
57 renderItem={({ item }) => (
58 <Item
59 id={item.id}
60 title={item.title}
61 selected={!!selected.get(item.id)}
62 onSelect={onSelect}
63 />
64 )}
65 keyExtractor={item => item.id}
66 extraData={selected}
67 />
68 </SafeAreaView>
69 );
70}
71
72const styles = StyleSheet.create({
73 container: {
74 flex: 1,
75 marginTop: Constants.statusBarHeight,
76 },
77 item: {
78 backgroundColor: '#f9c2ff',
79 padding: 20,
80 marginVertical: 8,
81 marginHorizontal: 16,
82 },
83 title: {
84 fontSize: 32,
85 },
86});
  • data : Array객체를 요구하며 필수값이다.
  • ItemSeperatorComponent : 아이템 사이의 구분선을 정의한다.
  • numColums : 행의 개수를 정의한다.
  • onEndReached: 스크롤의 마지막에 닿으면 콜하는 함수를 정의한다.
  • onRefresh : 새로고침시 호출하는 함수를 정의한다.

Section List

Flat List에서 Section별 기능을 추가한 리스트

1import React from 'react';
2import {
3 StyleSheet,
4 Text,
5 View,
6 SafeAreaView,
7 SectionList,
8} from 'react-native';
9import Constants from 'expo-constants';
10
11const DATA = [
12 {
13 title: 'Main dishes',
14 data: ['Pizza', 'Burger', 'Risotto'],
15 },
16 {
17 title: 'Sides',
18 data: ['French Fries', 'Onion Rings', 'Fried Shrimps'],
19 },
20 {
21 title: 'Drinks',
22 data: ['Water', 'Coke', 'Beer'],
23 },
24 {
25 title: 'Desserts',
26 data: ['Cheese Cake', 'Ice Cream'],
27 },
28];
29
30function Item({ title }) {
31 return (
32 <View style={styles.item}>
33 <Text style={styles.title}>{title}</Text>
34 </View>
35 );
36}
37
38export default function App() {
39 return (
40 <SafeAreaView style={styles.container}>
41 <SectionList
42 sections={DATA}
43 keyExtractor={(item, index) => item + index}
44 renderItem={({ item }) => <Item title={item} />}
45 renderSectionHeader={({ section: { title } }) => (
46 <Text style={styles.header}>{title}</Text>
47 )}
48 />
49 </SafeAreaView>
50 );
51}
52
53const styles = StyleSheet.create({
54 container: {
55 flex: 1,
56 marginTop: Constants.statusBarHeight,
57 marginHorizontal: 16,
58 },
59 item: {
60 backgroundColor: '#f9c2ff',
61 padding: 20,
62 marginVertical: 8,
63 },
64 header: {
65 fontSize: 32,
66 },
67 title: {
68 fontSize: 24,
69 },
70});

Image

URL 이미지, 디바이스 이미지 등 다양한 형태의 이미지를 지원한다.

1import React, { Component } from 'react';
2import { View, Image } from 'react-native';
3
4export default class DisplayAnImage extends Component {
5 render() {
6 return (
7 <View>
8 <Image
9 style={{width: 50, height: 50}}
10 source={require('@expo/snack-static/react-native-logo.png')}
11 />
12 <Image
13 style={{width: 50, height: 50}}
14 source={{uri: 'https://facebook.github.io/react-native/img/tiny_logo.png'}}
15 />
16 <Image
17 style={{width: 66, height: 58}}
18 source={{uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg=='}}

안드로이드 기기에 GIF나 URL이미지를 추가할 때는 build.gradle에 dependencies를 추가해줘야한다.

1dependencies {
2 // If your app supports Android versions before Ice Cream Sandwich (API level 14)
3 implementation 'com.facebook.fresco:animated-base-support:1.10.0'
4
5 // For animated GIF support
6 implementation 'com.facebook.fresco:animated-gif:1.12.0'
7
8 // For WebP support, including animated WebP
9 implementation 'com.facebook.fresco:animated-webp:1.10.0'
10 implementation 'com.facebook.fresco:webpsupport:1.10.0'
11
12 // For WebP support, without animations
13 implementation 'com.facebook.fresco:webpsupport:1.10.0'
14}
  • resizeMode : 이미지가 컨테이너 사이즈와 다를 시 정렬 모드를 설정한다. cover/contain/stretch/repeat/center
  • resizeMethod : 이미지가 컨터이너 사이즈와 다를 시 맞춤 모드를 설정한다. auto/resize/scale
  • defaultSource: 기본 이미지를 설정한다. 로컬 이미지로 설정할 때는 require('./path/to/image.png')와 같이 설정한다.
  • getSize: 이미지의 사이즈를 반환한다.

ImageBackground

화면의 배경을 이미지로 설정하고자 할때 사용한다.

1return (
2 <ImageBackground source={...} style={{width: '100%', height: '100%'}}>
3 <Text>Inside</Text>
4 </ImageBackground>
5);

View

UI를 구성할 때 가장 기본이 되는 것. flexbox, style, some touch handling, accessibility를 지원한다.

자세한 내용은 공식문서 에서 확인가능하다.

1class ViewColoredBoxesWithText extends Component {
2 render() {
3 return (
4 <View
5 style={{
6 flexDirection: 'row',
7 height: 100,
8 padding: 20,
9 }}>
10 <View style={{backgroundColor: 'blue', flex: 0.3}} />
11 <View style={{backgroundColor: 'red', flex: 0.5}} />
12 <Text>Hello World!</Text>
13 </View>
14 );
15 }
16}

SafeAreaView

IOS 11 버전 이상에서 지원되는 뷰이다. 홈버튼이 없고 제스쳐로 드래그하여 화면을 조정하므로 그 영역에 겹치지 않도록 설정하는 것이다

1import React from 'react';
2import { StyleSheet, Text, SafeAreaView } from 'react-native';
3
4export default function App() {
5 return (
6 <SafeAreaView style={styles.container}>
7 <Text>Page content</Text>
8 </SafeAreaView>
9 );
10}
11
12const styles = StyleSheet.create({
13 container: {
14 flex: 1,
15 },
16});

ScrollView

길어지는 뷰에 스크롤을 추가한다.

1import React from 'react';
2import { StyleSheet, Text, SafeAreaView, ScrollView } from 'react-native';
3import Constants from 'expo-constants';
4
5export default function App() {
6 return (
7 <SafeAreaView style={styles.container}>
8 <ScrollView style={styles.scrollView}>
9 <Text style={styles.text}>
10 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
11 eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
12 minim veniam, quis nostrud exercitation ullamco laboris nisi ut
13 aliquip ex ea commodo consequat. Duis aute irure dolor in
14 reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
15 pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
16 culpa qui officia deserunt mollit anim id est laborum.
17 </Text>
18 </ScrollView>
19 </SafeAreaView>
20 );
21}
22
23const styles = StyleSheet.create({
24 container: {
25 flex: 1,
26 marginTop: Constants.statusBarHeight,
27 },
28 scrollView: {
29 backgroundColor: 'pink',
30 marginHorizontal: 20,
31 },
32 text: {
33 fontSize: 42,
34 },
35});

TextInput

1import React, { Component } from 'react';
2import { TextInput } from 'react-native';
3
4export default function UselessTextInput() {
5 const [value, onChangeText] = React.useState('Useless Placeholder');
6
7 return (
8 <TextInput
9 style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
10 onChangeText={text => onChangeText(text)}
11 value={value}
12 />
13 );
14}
  • autoCapitalize : characters/ words/ sentences/ none
  • defaultValue : 기본값

RefreshControl

Pull to refresh를 가능하게 하는 UI

1lass Screen extends Component<Props, State> {
2 static navigationOptions = {
3 title: 'RefreshControl',
4 };
5
6 timeout;
7
8 state = {
9 refreshing: false,
10 };
11
12 _onRefresh = () => {
13 this.setState({refreshing: true});
14 this.timeout = setTimeout(() => {
15 this.setState({refreshing: false});
16 }, 3000);
17 }
18
19 componentWillUnmount = () => {
20 if (this.timeout) {
21 clearTimeout(this.timeout);
22 this.timeout = null;
23 }
24 }
25
26 render() {
27 return (
28 <View style={styles.container}>
29 <ScrollView
30 contentContainerStyle={{
31 justifyContent: 'center',
32 alignItems: 'center',
33 }}
34 style={{
35 alignSelf: 'stretch',
36 }}
37 refreshControl={
38 <RefreshControl
39 refreshing={this.state.refreshing}
40 onRefresh={this._onRefresh}
41 />
42 }
43 >
44 <Text>text</Text>
45 <Text>text</Text>
46 <Text>text</Text>
47 <Text>text</Text>
48 <Text>text</Text>
49 <Text>text</Text>
50 <Text>text</Text>
51 <Text>text</Text>
52 <Text>text</Text>
53 <Text>text</Text>
54 <Text>text</Text>
55 <Text>text</Text>
56 <Text>text</Text>
57 <Text>text</Text>
58 <Text>text</Text>
59 <Text>text</Text>
60 <Text>text</Text>
61 <Text>text</Text>
62 <Text>text</Text>
63 <Text>text</Text>
64 <Text>text</Text>
65 <Text>text</Text>
66 <Text>text</Text>
67 <Text>text</Text>
68 <Text>text</Text>
69 </ScrollView>
70 </View>
71 );
72 }
73}
74
75export default Screen;
  • Refreshing : 화면이 리프레쉬 되고 있는지를 반환함 (true/false)
  • onRefresh: 새로고침 시 호출하는 함수 정의
  • Colors : 인디케이터 색 정의 (안드로이드에서만 가능)
  • tintColor : 인디케이터 색 정의 (IOS에서만 가능)

Switch

1class Screen extends Component<Props, State> {
2 static navigationOptions = {
3 title: 'Switch',
4 };
5
6 state = {
7 val: false,
8 };
9
10 onValChange = (val) => {
11 console.log('onValChange');
12 this.setState({
13 val,
14 });
15 }
16
17 render() {
18 return (
19 <View style={styles.container}>
20 <Switch
21 onValueChange={this.onValChange}
22 value={this.state.val}
23 />
24 </View>
25 );
26 }
27}
28
29export default Screen;
  • disabled: true로 설정하면 스위치를 토글할 수 없음
  • onValueChange: 값이 바뀌면 호출할 함수를 정의한다.