— React, ReactNative, TIL — 2 min read
React Native에서 사용하는 컴포넌트들에 대한 설명을 정리한다.
공식문서 에서 자세한 설명이나 빠진 부분을 찾아볼 수 있다.
1<View style={styles.container}>2 <Button3 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>
1<View style={styles.container}>2 <View3 style={{4 marginTop: 40,5 justifyContent: 'center',6 }}7 >8 <ActivityIndicator9 size="large" color="#0000ff"10 />11 </View>12 <View13 style={{14 marginTop: 40,15 justifyContent: 'center',16 }}17 >18 <ActivityIndicator19 size="small"20 color="black"21 />22 </View>23 <View24 style={{25 marginTop: 40,26 justifyContent: 'center',27 }}28 >29 <ActivityIndicator30 animating={false}31 size="large"32 color="black"33 hidesWhenStopped={false}34 />35 </View>36 {/* <View37 style={{38 marginTop: 40,39 justifyContent: 'center',40 }}41 >42 <ActivityIndicator43 size={'40'}44 color='#3d3d3d'45 />46 </View> */}47 </View>
시간, 날짜를 선택하는 피커화면을 만든다. 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 <DatePickerIOS20 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});
안드로이드의 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 <DrawerLayoutAndroid9 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},
기본적인 리스트뷰를 만들어준다. 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 <FlatList32 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 <TouchableOpacity29 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 <FlatList56 data={DATA}57 renderItem={({ item }) => (58 <Item59 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});
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 <SectionList42 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});
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 <Image9 style={{width: 50, height: 50}}10 source={require('@expo/snack-static/react-native-logo.png')}11 />12 <Image13 style={{width: 50, height: 50}}14 source={{uri: 'https://facebook.github.io/react-native/img/tiny_logo.png'}}15 />16 <Image17 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 support6 implementation 'com.facebook.fresco:animated-gif:1.12.0'7
8 // For WebP support, including animated WebP9 implementation 'com.facebook.fresco:animated-webp:1.10.0'10 implementation 'com.facebook.fresco:webpsupport:1.10.0'11
12 // For WebP support, without animations13 implementation 'com.facebook.fresco:webpsupport:1.10.0'14}
화면의 배경을 이미지로 설정하고자 할때 사용한다.
1return (2 <ImageBackground source={...} style={{width: '100%', height: '100%'}}>3 <Text>Inside</Text>4 </ImageBackground>5);
UI를 구성할 때 가장 기본이 되는 것. flexbox, style, some touch handling, accessibility를 지원한다.
자세한 내용은 공식문서 에서 확인가능하다.
1class ViewColoredBoxesWithText extends Component {2 render() {3 return (4 <View5 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}
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});
길어지는 뷰에 스크롤을 추가한다.
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 do11 eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad12 minim veniam, quis nostrud exercitation ullamco laboris nisi ut13 aliquip ex ea commodo consequat. Duis aute irure dolor in14 reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla15 pariatur. Excepteur sint occaecat cupidatat non proident, sunt in16 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});
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 <TextInput9 style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}10 onChangeText={text => onChangeText(text)}11 value={value}12 />13 );14}
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 <ScrollView30 contentContainerStyle={{31 justifyContent: 'center',32 alignItems: 'center',33 }}34 style={{35 alignSelf: 'stretch',36 }}37 refreshControl={38 <RefreshControl39 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;
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 <Switch21 onValueChange={this.onValChange}22 value={this.state.val}23 />24 </View>25 );26 }27}28
29export default Screen;