리엑트 네이티브 = 리액트(react) + 네이티브 (navtive)
프론트 개발 기술 중에 하나이다! 프론트 앤드로 앱을 만들 수 있게 해주는 라이브러리이다.
Expo는 자바스크립트를 이용하여 각 운영체제(IOS, 안드로이드)에 맞는 코드들로 변환하여 쉽게 도움을 받을 수 있다.
node와 npm
자바스크립트에서 사용하는 도구를 사용하기 위한 도구를 가져오는 역할을 한다.
(도구를 가져오기 위해 도구를 사용한다!)
Yarn
npm 도구로 사용하는 도구이다.
더 효율적인 속도를 내기 위해 설치하는 도구이다.
↓ cmd 창에서 이 코드를 입력해 yarn을 설치한다.
npm install -g yarn
Expo
cmd에 expo 공구함을 설치하여 어디서든 expo를 사용할 수 있게 설치해준다.
npm install -g expo-cli
expo를 설치하여
우리는
프로젝트 생성
프로젝트 실행
프로젝트 빌드 등의 여러 기능들을 사용 할 수 있다.
expo를 사용하기 위해서 Expo 서비스에 회원가입을 해야 한다.
회원가입을 하고, 개인 컴퓨터 cmd에서 expo login --username "____" 을 치면
expo 서비스와 내 컴퓨터가 연결된다.
expo를 설치하는 방법들
asset 폴더
앱에서 사용되는 사진을 넣는 폴더
node_modules 폴더
앱을 개발할 때 사용할 도구들이 있는 폴더
app.json
앱을 설명해주는 설명서라고 할 수 있다.
expo가 큐알코드를 보여줘서 핸드폰으로 코드를 찍으면 expo 클라이언트 앱이 깔려 있다면
바로 앱화면을 스마트폰에서 볼 수 있다.
앱을 실행시키고 싶다면?
터미널 창에서
expo start
코드를 쳐야 한다.
※ 이때 주의할 점, windows에서는 프롬프트 창이 꼭 cmd 창으로 되어 있어야 오류가 생기지 않으니
이곳을 cmd로 변환하여 expo start 명령을 입력해야 한다.
JSX 문법
앱 화면을 그릴 때 JSX 문법을 사용하는데, < > 안에 코드가 들어 있다.
<View style={styles.container}> <Text>Open up App.js to start working on your app!</Text> <StatusBar style="auto" /> </View>
태그로 화면을 그린다.
App() 이라는 함수가 앱의 화면을 return(반환)하는데, 이것을 랜더링(rendering)한다고 표현한다.
앞으로 사용할 태그(앨리먼트)들은 'react-native'에서 가져온다고 생각해야 한다.
App.js에서 보면,
import { StyleSheet, Text, View } from 'react-native';
라는 코드를 볼 수 있다. 리엑트 네이티브에서 가져온다고 명시해야 한다. (라이브러리)
여는 태그, 닫는 태그 주의!!
꼭 한 쌍으로 사용한다.
모든 태그들은 모든 태그를 감싸는 최상위 태그가 존재해야 한다. 또한, 모든 태그를 감싸고 있는 최상위 태그를 감싸는 () 소괄호가 있어야 한다.
(
< >
</>
)
주석 다는 방법
JSX 밖에서 주석을 달기 위해서는
//주석 내용
// -> /를 두번 사용하여 주석을 처리한다.
하지만,
JSX 안 < > 태그 안에서는
{/* 주석 내용 */}
좀 더 복잡한 모습으로 주석을 작성해야 한다.
* 여기서 Tip!
주석을 그냥 작성하고, 드래그하여 ctrl + /를 누르면 자동으로 주석을 만들어 준다!!
귀찮게 {/ */} 작성하지 말고, ctrl + / 사용하자!
<view> </view>
화면에 영역을 잡아주는 태그이다.
view 태그는 StyleSheet를 사용하여 스타일을 지정할 수 있다.
문자를 쓰기 위해서는 꼭!! 태그 안에 작성해야 한다.
태그 안에 쓰면 에러 발생!
화면보다 넘치는 정보를 담고 있는 경우, 스크롤 해서 정보들이 보일 수 있게 해주는 태그이다.
이 태그를 사용하려면 무엇이 먼저 되어야 할까?
바로 reat-native에서 꺼내서 써야 한다.!!
import { StyleSheet, Text, View, ScrollView } from 'react-native';
<Button style={styles.buttonStyle} title="버튼입니다 " color="#f194ff" onPress={function(){ Alert.alert('팝업 알람입니다!!') }} />
버튼 태그는 스스로 닫는 태그이다.
title이라는 속성은 버튼의 내용을 담는 것이고,
color는 버튼의 색
onPress는 버튼이 눌러졌을 때 어떤 기능이 실행될지 구현해주는 것이다. 함수에 연결하여 사용한다.
Alert
import { StyleSheet, Text, View, Button, Alert } from 'react-native'; Alert.alert('팝업 알람입니다!!')
리액트 네이티브에서 Alert 기능을 가져와 페이지에 추가한 다음, 연결 연산자(.)로 연결하여 Alert 명령어를 사용한다.
예제에서는 버튼을 누르면 alert이 뜨도록 해놨다.
Alert 기능을 외부에 함수로 만들어서 작성할 수 있다.
const customAlert = () => { Alert.alert("JSX 밖에서 함수 구현 가능!") } <Button style={styles.buttonStyle} title="버튼입니다 " color="#f194ff" onPress={customAlert} />
onPress={customAlert}처럼 바로 함수 이름을 작성하여 실행시킬 수 있고,
<Button style={styles.buttonStyle} title="버튼입니다 " color="#FF0000" onPress={() => {customAlert()}} />
화살표 함수를 사용하여 함수 이름 옆에 ()를 붙여 사용할 수도 있다.
영역을 생성하는 명령어이다. 역역을 누를 수 있는 기능이고, TouchableOpacity로 감싸 onPress 함수로 연결하면 버튼 역할을 할 수 있게 된다.
<TouchableOpacity style={styles.textContainer} onPress={customAlert}> <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text> </TouchableOpacity>
assets 폴더에 있는 이미지를 가져와 사용하는 (import)와 외부 이미지 링크를 넣어서 사용하는 방식 (uri) 2가지가 있다.
import favicon from "./assets/favicon.png" <Image source={favicon} // 사용설명서에 나와 있는 resizeMode 속성 값을 그대로 넣어 적용합니다 resizeMode={"repeat"} style={styles.imageStyle} />
resizeMode에는 다양한 방법으로 이미지를 변화시킬 수 있는 속성이다.
resizeMode={"cover"}
resizeMode에 cover를 넣으면
이렇게 화면을 꽉 채우는 모습으로 이미지가 보여진다.
외부 이미지를 사용하려면 uri 를 사용한다.
source={{uri:'https://images.unsplash.com/photo-1424819827928-55f0c8497861?fit=crop&w=600&h=600%27'}} resizeMode={"cover"} style={styles.imageStyle}
외부 무료 이미지 링크를 source 속성에 입력하여 앱 이미지로 사용할 수 있다.
const styles = StyleSheet.create();
뼈대에 옷을 입혀주는 스타일 코드 함수다!
함수라는 것을 기억하여 ( ) 빼먹지 않을 수 있도록 해야함
<View style={styles.container}>
↑ 이 코드를 보면 view 태그에 style={styles.conatiner}라는 카거 연결된 것을 볼 수 있다.
영역에 옷을 입혀주는 것이라 생각하면 된다!!
<View style={styles.container}> container: { //영역을 잡는 속성입니다. 따로 자세히 다룹니다. //flex: 1은 전체 화면을 가져간다는 뜻입니다 flex: 1, //영역의 배경 색을 결정합니다 backgroundColor: '#fff', //아래 두 속성은 영역 안의 컨텐츠들의 배치를 결정합니다. //flex를 자세히 다룰때 같이 자세히 다룹니다 justifyContent:"center", alignContent:"center" }
앱 화면의 스타일을 구성할 때 보여지는 곳을 꾸밀 때 사용하는 속성
margin: 컨텐츠 밖에서의 여백
padding: 컨텐츠 안에서의 여백
borderRadius: 테두리의 가장자리
borderWidth: 테두리의 두께
borderColor: 테두리의 색깔
borderStyle: 테두리의 속성
(ex. dotted: 점선)
color: 글자 색 설정
fontSize: 글자 크기 결정
fontWeight: 글자 두께 (100 단위로 커짐)
textAlign: 글자의 위치를 결정
flex: 1 ==> 전체 화면을 다 가져간다.
export default function App() { return ( <View style={styles.container}> <View style={styles.containerOne}> </View> <View style={styles.containerTwo}> </View> </View> ); } const styles = StyleSheet.create({ container: { flex:1 }, containerOne: { flex:1, backgroundColor:"red" }, containerTwo:{ flex:2, backgroundColor:"yellow" } });
안에 2개의 컨테이너들이 한 화면을 나눠 갖게 되는데, 그 때 containerOne은 1을 가지고, containerTwo는 2를 가지게 된다.
1+2 = 3 이니 화면을 3등분 하여 1/3은 빨강이, 2/3은 노랑이 차지하게 된다.
import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; export default function App() { return ( <View style={styles.container}> <View style={styles.containerOne}> </View> <View style={styles.containerTwo}> <View style={styles.innerOne}> </View> <View style={styles.innerTwo}> </View> </View> </View> ); } const styles = StyleSheet.create({ container: { flex:1 }, containerOne: { flex:1, backgroundColor:"red" }, containerTwo:{ flex:2, backgroundColor:"yellow" }, innerOne: { flex:1, backgroundColor:"blue" }, innerTwo: { flex:4, backgroundColor:"orange" } });
blue는 1/5 orange는 4/5 영역을 전체 화면의 2/3를 차지하는 containerTwo 에서 나눠 갖게 된다.
즉, flex는 상대적이다.
안에 있는 영역이 바깥의 영역의 비율로 따져서 몇분의 몇을 가져가는지를 flex로 정하게 된다.
flex는 위치한 곳의 영역을 같은 레벨의 flex 합 비율대로 가져가게 된다!!
import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; export default function App() { return ( <View style={styles.container}> <View style={styles.containerOne}> </View> <View style={styles.containerTwo}> <View style={styles.innerOne}> </View> <View style={styles.innerTwo}> </View> </View> </View> ); } const styles = StyleSheet.create({ container: { flex:1 }, containerOne: { flex:1, backgroundColor:"red" }, containerTwo:{ flex:2, flexDirection:"row", backgroundColor:"yellow" }, innerOne: { flex:1, backgroundColor:"blue" }, innerTwo: { flex:4, backgroundColor:"orange" } });
flexDirection:"row"의 의미는 좌우를 의미한다.
flexDirection:"column"은 상하를 의미한다.
flexDirection의 default 값은 기본 cloumn이다. 그래서 flexDirectiond을 따로 지정하지 않으면 화면이 정렬된다.
innerOne: { flex:2, backgroundColor:"blue" }, innerTwo: { flex:2, backgroundColor:"orange" }
inner의 비율을 2:2로 바꾸었을 때,
justifyContent는 flexDirection과 동일한 방향으로 정렬하는 속성이다.
const styles = StyleSheet.create({ container: { flex:1 }, containerOne: { flex:1, backgroundColor:"red" }, containerTwo:{ flex:2, flexDirection:"row", backgroundColor:"yellow" }, innerOne: { flex:1, backgroundColor:"blue" }, innerTwo: { flex:4, justifyContent:"flex-start", backgroundColor:"orange" } });
justifyContent가 flext-start로 지정되면, orange 영역의 가장 왼쪽 위로 가서 text가 붙게 된다.
justifyContent가 flext-end 로 지정되면,
이렇게 왼쪽 아래로 지정된다.
현재 코드에서는 flexDirection이 default 값인 column으로 지정되어 있어서 content가 상하로 움직이는데, 만약 flexDirection이 row로 지정되면,
innerTwo: { flex:4, flexDirection:"row", justifyContent:"flex-start", backgroundColor:"orange" }
justifyContent:"flex-start"는 왼쪽 위에 붙는 것이 동일하지만, justifyContent:"flex-end"는 오른쪽을 붙는 것을 알 수 있다.
left, right 대신에 flex-start, flex-end가 있다고 생각하면 된다!
justifyContent:"center"도 가능하다.
flexDirection과 반대 방향이라고 생각하면 된다.
innerTwo: { flex:4, flexDirection:"row", alignItems:"center", backgroundColor:"orange" }
현재 flexDirection이 row 이고, alignItems가 center 이다. row라는 것은 좌우 정렬이기 때문에, 원래 같아서 center를 잡으면 orange 영역의 위쪽의 가운데에 text가 위치해야 한다.
하지만, alignItems는 flexDirection과 반대 방향으로 content를 두기 때문에 cloumn으로 설정한 것 처럼 상하를 기준으로 text를 배칫한다.
이 코드가 가장 리액트 네이티브의 가장 기초가 되기 때문에 잘 알고 있을 것!
import React from 'react'; import main from './assets/main.png'; import { StyleSheet, Text, View, Image, TouchableOpacity, ScrollView } from 'react-native'; export default function App() { console.disableYellowBox = true; //return 구문 밖에서는 슬래시 두개 방식으로 주석 return () } const styles = StyleSheet.create({}
앱 만들기에 대해선 과정을 상세하게 작성하려 하면 너무 복잡해질 것 같아 코드를 짜면서 다시 공부해보야야 할 것들에 대해서만 기록해보려 한다.
alignSelf: 전체를 flex로 잡지 않아도 content 스스로 위치를 잡을 수 있게 해줌
width:"90%" : 문자열로 content의 %를 잡을 수 있다.
ScrollView를 수평으로 스크롤 하기 위해서는
<ScrollView horizontal={true}>
코드를 넣어 좌우로 (수평으로) 스크롤 할 수 있다.
이미지는 고유한 영역을 지정해 주어야지만, 화면에 출력된다.
width나 height, flex 같은 속성들로 위치를 지정해 주어야 한다.
상위 태그를 < Text >로 작성한 경우
<Text style={styles.cardText}> <Text style={styles.cardTitle}>먹다 남은 피자를 촉촉하게!</Text> <Text style={styles.cardDesc} numberOfLines={3}>먹다 남은 피자는 수분이 날라가기 때문에 처음처럼 맛있게 먹을 수 없는데요. 이럴 경우 그릇에 물을 받아 전자레인지 안에서 1분 30초에서 2분 정도 함께 돌려주면 촉촉하게 먹을 수 있습니다. 물이 전자레인지 안에서 수증기를 일으키고, 피자에 촉촉함을 더해줍니다.</Text> <Text style={styles.cardDate}>2020.09.09</Text> </Text>
앱 화면에서 줄바꿈이나 numberOfLines가 실행되지 않는 다는 것을 볼 수 있다.
하지만,
상위 태그를 < View >로 변경하면,
<View style={styles.cardText}> <Text style={styles.cardTitle}>먹다 남은 피자를 촉촉하게!</Text> <Text style={styles.cardDesc} numberOfLines={3}>먹다 남은 피자는 수분이 날라가기 때문에 처음처럼 맛있게 먹을 수 없는데요. 이럴 경우 그릇에 물을 받아 전자레인지 안에서 1분 30초에서 2분 정도 함께 돌려주면 촉촉하게 먹을 수 있습니다. 물이 전자레인지 안에서 수증기를 일으키고, 피자에 촉촉함을 더해줍니다.</Text> <Text style={styles.cardDate}>2020.09.09</Text> </View>
줄바꿈과 numberOfLines가 잘 동작되는 것을 볼 수 있다!!
즉, 상위 태그가 어떤 것인가에 따라서 보여지는 화면이 다르기 때문에 주의해서 작성해야 한다!
expo를 정상적으로 멈추는 방법: Ctrl + C 를 누르기 (까먹었음..)
모듈 시스템으로 map 함수를 이용해 data.json 을 불러온다.
JSX 문법 안에서 자바스크립트 변수를 쓰려면 { } 로 감싸야 한다.
<Text style={styles.weather}>오늘의 날씨: {todayWeather + '°C ' + todayCondition} </Text>
또한, 문법을 사용할 때도, 중괄호 { }를 사용한다.
반복문을 돌릴 때는 가상 상위의 태그에는 반문으로 사용될 키(key)값이 주어지고 각 content가 유니크(index) 해야 한다.
** 다시 복습하는 map 함수
map 함수는 리스트의 길이를 몰라도 된다.
map ((value, i) => { }
value는 리스트의 내용을 의미하고, i는 리스트의 index 번호를 의미한다.
let result = 10 > 2 ? "참" : "거짓" let result = 조건 ? 참일 때 : 거짓 일때
앱 만들기 예제에서는 홀수 카드에서 배경에 색을 넣는 방법으로 삼항 연산자를 사용했다.
tip.map((content,i)=>{ return i % 2 == 0 ? (<View style={styles.cardEven} key={i}> <Image style={styles.cardImage} source={{uri:content.image}}/> <View style={styles.cardText}> <Text style={styles.cardTitle} numberOfLines={1}>{content.title}</Text> <Text style={styles.cardDesc} numberOfLines={3}>{content.desc}</Text> <Text style={styles.cardDate}>{content.date}</Text> </View> </View>) : (<View style={styles.cardOdd} key={i}> <Image style={styles.cardImage} source={{uri:content.image}}/> <View style={styles.cardText}> <Text style={styles.cardTitle} numberOfLines={1}>{content.title}</Text> <Text style={styles.cardDesc} numberOfLines={3}>{content.desc}</Text> <Text style={styles.cardDate}>{content.date}</Text> </View> </View>) })
간략하게 작성하면 ,
tip.map((content, i) => {
return i % 2 == ? ( ) : ( )
})
으로 쓸 수 있다.
파일 이름과 함수의 이름은 같아야 한다.
상하좌우 가운데 (=정가운데)로 맞추는 방법
justifyContent:"center", alignItems:"center",
content의 기본 flex 방향은 column으로 상하 기준으로 되어 있기 때문에, justifyContent:"center"하면 상하의 중심을 뜻하고, alignItems:"center"면 상하의 반대인 좌우 정렬이 되어 정가운데에 아이템이 놓이게 된다.
해설영상을 보지 않고 최대한 만들려고 하였고, 가운데 정렬하는 부분이 정말 까다로워서 정렬부분만 해설 영상을 참고했다!
그래도 내힘으로 앱화면을 만들어 보니 나도 내가 만들어보고 싶은 앱 화면을 만들 수 있겠다는 자신감이 들어서 좋다!!
화면을 만들면서 들었던 생각이 CSS로 웹 화면 꾸미는 것과 비슷하다는 느낌을 정말 많이 받았다. 기말고사로 웹 페이지를 꾸면서 하나의 서비스를 제공하는 기말과제가 있었는데, 그 과제를 하며 CSS를 정말 열심히 공부했었다. 그런데 다행이 앱 화면도 CSS와 느낌이 비슷하게 가서 미리 감각을 세워나 맨땅에 헤딩하는 것보다는 자신감을 가지고 숙제를 할 수 있어서 좋았다!
다음 주차에서 어떤 새로운 기능들을 배울지 기대가 된다.