-
React Native 002React/React Native 2022. 12. 30. 02:01728x90
미국에 돌아온 지 3일째다 시차적응 때문에 힘들고.. 어제까지는 수업 수료하는 날이라 바쁘고 와이프 비자 발급 받으라 정신이 없었는데 오늘은 내 신분 챙기는 서류 보내느라 바빴다. 그래도 인터뷰때 한 마디라도 더 해보려면 어느정도 앱을 만들어 봐야 할 것 같아서 남은 시간 더 해보자..
Core Components
주로 사용되는 컴포넌트들은 이런게 있다
Todo App만들기
목표 : 리액트 네이티브의 core components를 최대한 많이 사용하면서 개발하기
코어 컴포넌트 확인 https://reactnative.dev/docs/components-and-apis
구조
rnfes - 코어 컴포넌트 사용
App.js에 있는 ui를 MainScreen으로 가져온다
import { SafeAreaView, StyleSheet, Text, View } from 'react-native' import React from 'react' const MainScreen = () => { return ( <SafeAreaView> <Text>ToDo App</Text> </SafeAreaView> ) } export default MainScreen const styles = StyleSheet.create({})
<SafeAreaView>
이것의 목적은 장치의 안전 영역 경계 내에서 콘텐츠를 렌더링하는 것
(현재 iOS 버전 11 이상이 설치된 iOS기기 에만 적용된다.)SafeAreaView를 적용하지 않으면 이렇게 된다. <StatusBar> 컴포넌트
앱의 상태 표시줄을 제어하는 구성요소이다. 상태 표시줄은 일반적으로 화면 상단에 있는 영역으로 현재시간, WiFi 및 배터리 정보 아이콘을 표시한다. https://reactnative.dev/docs/statusbar
StatusBar · React Native
Component to control the app's status bar. The status bar is the zone, typically at the top of the screen, that displays the current time, Wi-Fi and cellular network information, battery level and/or other status icons.
reactnative.dev
적용하면서 바꿔볼 수 있다. 간단하게 만들어보자
import { SafeAreaView, StyleSheet, Text, View, StatusBar } from 'react-native' import React from 'react' const MainScreen = () => { return ( <SafeAreaView> <StatusBar barStyle={'default'} /> <Text>ToDo App</Text> <View> <Text>할 일</Text> </View> <View> <Text>완료된 일</Text> </View> </SafeAreaView> ) } export default MainScreen const styles = StyleSheet.create({})
잘 출력된다. StyleSheet 사용하기
https://reactnative.dev/docs/style
Style · React Native
With React Native, you style your application using JavaScript. All of the core components accept a prop named style. The style names and values usually match how CSS works on the web, except names are written using camel casing, e.g. backgroundColor rathe
reactnative.dev
web은 css를 사용해서 스타일링을 하는데 React Native에서는 css가 아닌 JS를 사용해서 스타일링을 한다.
코어 컴포넌트에 styles prop을 가지고 있다. 카멜케이스를 사용하면 된다.
인라인 스타일로 넣어줄 수도 있고 StyleSheet를 사용해 넣어줄 수도 있다. 역시 이 방법이 가독성이 좋기 때문에 더 추천된다. 이미 정해놓은 스타일을 캐시해주기 때문에 성능도 좋아지게 된다.예시
import { Platform, SafeAreaView, StyleSheet, Text, View} from 'react-native' import React from 'react' import { StatusBar } from 'expo-status-bar' const MainScreen = () => { return ( <SafeAreaView style={styles.container}> <StatusBar barStyle={'default'}></StatusBar> <Text style={styles.pageTitle}>ToDo App</Text> <View style={styles.listView}> <Text style={styles.listTitle}>할 일</Text> </View> <View style={styles.separator} /> <View style={styles.listView}> <Text style={styles.listTitle}>완료된 일</Text> </View> </SafeAreaView> ) } export default MainScreen const styles = StyleSheet.create({ container:{ flex:1, paddingTop: Platform.OS==='android'? 20 : 0, //안드로이드일때는 20을 아니면 0 backgroundColor: '#F7f8fa', }, pageTitle:{ marginBottom:35, paddingHorizontal:15, fontSize:54, fontWeight:'600', }, separator:{ marginHorizontal:10, marginTop:25, marginBottom:10, borderBottomWidth:1, borderBottomColor:'#rgba(0,0,0,0.2)', }, listView:{ flex:1, }, listTitle:{ marginBottom:25, paddingHorizontal:15, fontSize:41, fontWeight:'500', } })
스타일을 입히는거는 사실 별반 다를게 없어 보인다. 근데 스타일시트를 따로 컴포넌트로 떼어서는 적용할 수 없는건가?
FlexBox
flex는 항목이 주 축을 따라 사용 가능한 공간을 채울 방법을 정의한다 각 요소의 속성 공간에 따라 분할된다.
web과 사용방법이 다르지 않다.InputForm
<KeyboardAvoidingView>
가상 키보드에서 벗어나야 하는 뷰의 일반적이 뭄ㄴ제를 ㅐ결하기 위한 구성요소. 키보드 높이에 따라 높이, 위치, 또는 아래쪽 패딩을 자동으로 조정한다.
behavior prop에 속성값을 줄 수 있다.
- padding 키보드가 열렸을 때 뷰의 하단에 패딩 설정
- height 뷰의 높이 자체 변경
- position 뷰의 위치 설정
import { KeyboardAvoidingView, Pressable, StyleSheet, Text, TextInput, View } from 'react-native' import React from 'react' const InputForm = () => { return ( <KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : 'height'} style={styles.addFormContainer}> <TextInput style={styles.inputField} placeholder="할 일을 작성해 주세요" /> <Pressable style={styles.addButton}> <Text style={styles.addButtonText}>+</Text> </Pressable> </KeyboardAvoidingView> ) } export default InputForm const styles = StyleSheet.create({ addFormContainer:{ flexDirection:'row', marginTop:'auto', marginBottom:30, paddingHorizontal:20, backgroundColor:'f7f8fa', }, inputField:{ flex:1, height:42, padding:5, marginRight:25, borderRadius:5, borderWidth:1, borderColor:'rgba0,0,0,0.2', color:'#000000', fontSize:16, textAlignVertical:'center', }, addButton:{ justifyContent:'center', alignItems:'center', width:42, height:42, borderRadius:4, borderWidth:1, backgroundColor:'rgba0,0,0,0.7', shadowOpacity:0.14, shadowRadius:8, shadowOffset: { width: 0, height: 4, } }, addButtonText:{ color:'#000000', fontSize:25, }, })
위 코드를 사용해 스타일까지 어느정도 준 모습이다.
안드로이드도 잘 나오고 아이폰도 잘 나온다 할일 체크리스트 생성하기
Pressable
누르는 것의 여러가지 state를 감지할 수 있다 얼마나 누르느냐에 따라 다양한 event 설정
핸드폰 화면은 작기때문에 체크박스의 조금 옆을 눌러도 체크되게 하는게 HitRect hitSlop
이런식으로 지정해줄 수 있는 것 PressRect
터치를(혹은 클릭을)하고 있는 와중에도(활성화 되고 있는 와중에) 어느정도 거리까지 활성화가 될지를 정할 수 있는 것
TodoItem.js
import { Pressable, StyleSheet, Text, View } from 'react-native' import React from 'react' const TodoItem = () => { return ( <View style={styles.itemContainer}> <Pressable style={styles.itemTextChecked} hitSlop={10} > </Pressable> <Text style={[styles.itemText, styles.itemTextChecked]}> 코딩하기 </Text> <Pressable style={[ styles.deleteButton, styles.deleteButtonDone ]} hitSlop={10} > </Pressable> <Text> </Text> </View> ) } export default TodoItem const styles = StyleSheet.create({})
리엑트 네이티브에서 svg 사용
리액트 네이티브는 svg 파일 지원을 안해서 모듈을 설치해야 한다.
- react-native-svg
npm install react-native-svg
- react-native-svh-transformer
임포트해서 사용하려면 이게 필요
npm install -D react-native-svg-transformer
metro.config.js 파일안에 넣어줄 코드가 있는데 npm웹사이트에서 확인이 가능하다.
https://www.npmjs.com/package/react-native-svg-transformer
react-native-svg-transformer
SVG transformer for react-native. Latest version: 1.0.0, last published: a year ago. Start using react-native-svg-transformer in your project by running `npm i react-native-svg-transformer`. There are 95 other projects in the npm registry using react-nativ
www.npmjs.com
프로젝트에 우클릭 New File을 해서 이름을 metro.config.js 로 지정해주고 아래 코드를 붙여넣기 한다.
const { getDefaultConfig } = require("expo/metro-config"); module.exports = (() => { const config = getDefaultConfig(__dirname); const { transformer, resolver } = config; config.transformer = { ...transformer, babelTransformerPath: require.resolve("react-native-svg-transformer"), }; config.resolver = { ...resolver, assetExts: resolver.assetExts.filter((ext) => ext !== "svg"), sourceExts: [...resolver.sourceExts, "svg"], }; return config; })();
이제 svg 사용할 준비는 되어있는데 https://www.svgrepo.com/ 이곳에서 다운 받을 수 있다.
다운 받은 파일들을 assets폴더에 넣어주고 이름에 맞춰 임포트도 해준다.
import { Pressable, StyleSheet, Text, View } from 'react-native'; import React from 'react'; import checkboxIcon from '../assets/checkbox.svg'; import checkboxCheckedIcon from '../assets/checkbox-checked.svg'; import deleteIcon from '../assets/delete.svg'; const TodoItem = () => { return ( <View style={styles.itemContainer}> <Pressable style={styles.itemTextChecked} hitSlop={10} > <checkboxIcon /> <checkboxCheckedIcon style={[styles.itemCheckboxCheckedIcon]} /> </Pressable> <Text style={[styles.itemText, styles.itemTextChecked]}> 코딩하기 </Text> <Pressable style={[ styles.deleteButton, styles.deleteButtonDone ]} hitSlop={10} > <deleteIcon /> </Pressable> <Text> </Text> </View> ) } export default TodoItem const styles = StyleSheet.create({})
적용을 해 주고 실행을 하면 짜잔
에러가 뜬다 - 버젼이 안맞는다 뭐라나 인데 하란대로 해주자 터미널에 아래를 입력해 설치한다.
npx expo install react-native-svg@13.4.0
그리고 나서 다시 실행하고 R을 눌러 리로드를 해주면
나온다! 혹시 아이콘이 크게 나오면 svg 파일로 들어가 크기를 수정 할 수 있다. import { Pressable, StyleSheet, Text, View } from 'react-native'; import React from 'react'; import CheckboxUnchecked from '../assets/checkbox-unchecked.svg'; import CheckboxChecked from '../assets/checkbox-checked.svg'; import DeleteIcon from '../assets/delete.svg'; const TodoItem = () => { return ( <View style={styles.itemContainer}> <Pressable style={styles.itemCheckbox} hitSlop={10} > <CheckboxUnchecked /> <CheckboxChecked style={[styles.itemCheckboxCheckedIcon]} /> </Pressable> <Text style={[styles.itemText, styles.itemTextChecked]}> 코딩하기 </Text> <Pressable style={[ styles.deleteButton, styles.deleteButtonDone ]} hitSlop={10} > <DeleteIcon /> </Pressable> <Text> </Text> </View> ) } export default TodoItem const styles = StyleSheet.create({ itemContainer:{ flexDirection: 'row', alignItems: 'center', paddingTop: 10, paddingBottom: 15, paddingHorizontal: 15, backgroundColor:'#f7f8fa', }, itemCheckbox:{ width: 20, height: 20, marginRight: 10, borderRadius: 5 }, itemCheckboxCheckedIcon:{ shadowColor: 'black', shadowOpacity:0.14, shadoeRadius: 10, shadowOffset: { width: 0, height: 4 }, }, itemText:{ marginRight:'auto', paddingRight:'auto', fontsize:15, lineHeight:20, color:'#737373' }, itemTextChecked:{ opacity:0.3, textDecorationLine:'line-through' }, deleteButton:{ opacity:0.8 }, deleteButtonDone:{ opacity:0.3 } })
대충 styles도 해줬고 결과
여기까지 하고 다음번에 기능을 입혀보자
728x90'React > React Native' 카테고리의 다른 글
React Native 003 (0) 2022.12.30 React Native 001 (0) 2022.12.27 React Native 000 (0) 2022.12.26