스파르타코딩클럽 - [왕초보] 나만의 수익성 앱, 앱개발 종합반 강의를 듣고 내용을 정리한 게시글입니다.
JSX
JSX
: 리액트 네이티브 앱 개발에서 구역(레이아웃)을 잡는 문법 언어
- 용도에 맞는 태그를 정해놓았기 때문에, 필요한 태그를 그때그때 꺼내서 사용하면 된다.
- 화면의 구역을 잡을 때는 <Vies> 태그
- 글자를 쓸 때는 <Text> 태그를 사용
▼ JSX 문법 예시
import { Text, View } from 'react-native';
<View>
<Text>Hello, I am {props.name}!</Text>
</View>
앱 개발 준비 - 리엑트 네이티브 & Expo 설치 및 실행
React Native
: 자바스크립트 언어 하나로 안드로이드 앱과 iOS앱 두가지 모두 만들어주는 라이브러리
- 하지만, 리엑트 네이티브로만 앱 개발을 하면, 특정 상황에서는 안드로이드, iOS 각각의 폴더에 들어가 직접 코드를 만져야 하는 상황이 발생함
-> 하나의 언어로 앱을 만들 수 있다는 취지에서 벗어나게 됨 ( yarn & expo 필요 )
yarn
: npm보다 가볍고 빠르게 자바스크립트 패키지를 관리할 수 있게 해주는 자바스크립트 패키지 매니저 툴
- yarn 설치 위해서는 npm 설치해야 함
- yarn 설치하기 명령어
$ npm install -g yarn
Expo
: 안드로이드 & iOS 코드를 건드려야 하는 대부분의 상황들을 안건드려도 되게끔 도와주는 프레임워크이자 플랫폼
- 개발 중인 앱 테스트를 위한 Expo Go 앱을 제공함
- Expo 명령어를 통해서 Expo Go 앱에서 개발 중인 앱을 그때그때 눈으로 확인 할 수 있음
- Expo를 설치 및 사용한다 => 프로젝트 생성 / 실행 / 빌드 등등의 여러 기능들을 사용할 수 있다
- Expo 설치하기 명령어 ( 관리자 권한으로 cmd 실행 )
$ npm install -g expo-cli
Expo 사용하기
- Expo 가입 필요 https://expo.dev/
- 로컬에 Expo 계정 세팅하기
$ expo login
아이디(or 이메일), 패스워드 입력하기 - vscode에서 프로젝트 폴더 열고 새 터미널에서 expo 프로젝트 생성하기
$ expo init myapp
- blank 선택 - 프로젝트 폴더 안으로 들어가기
$ cd myapp - expo 서버 실행하기
$ expo start - QR코드를 스마트폰으로 인식하기 ( 같은 네트워크에 연결되어 있어야 함 )
- expo 서버 종료하기
컨트롤 + c / command + c
Expo 프로젝트 기본 폴더 구조
- assets
: 앱이 동작되고 서비스되는데에 기본적으로 가지고 있는 이미지 및 아이콘 파일들을 담는 폴더 - node_modules
: 라이브러리들이 저장되는 장소 - App.js
: 앱이 시작되는 출발선이자 진입점
웹에서의 index.html 또는 main.html 같은 메인 파일 - App.json
: 앱의 이름, 앱의 출시 버전, 앱이 휴대폰에 설치될 때 보여질 아이콘, 앱이 켜질 때 보여지는 스플래시 스크린 화면, 안드로이드 또는 IOS 각각의 광고 설정 등 앱이 가지는 기본 정보들을 설정하는 파일
앱 화면 만들기 - JSX 문법
JSX 기본 문법
- 모든 태그는 가져와서 사용한다.
import { StyleSheet, Text, View } from 'react-native'; - 태그는 항상 닫는 태그와 자체적으로 닫는 태그를 구분해서 사용해야 한다.
- 모든 엘리먼트는 감싸는 최상위 엘리먼트가 있어야 한다.
- 엘리먼트 == 태그 - return에 의해 렌더링 될 땐 항상 소괄호로 감싸져야 한다.
- JSX 문법 밖에서의 주석과 안에서의 주석은 다르다.
return (
//JSX 밖에서의 주석
<View style={styles.container}>
{/*
JSX 문법 안에서의 주석
*/}
<Text>Open up App.js to start working on your app!</Text>
<StatusBar style="auto" />
</View>
);
앱 화면 만들기 - 화면을 구성하는 엘리먼트들
View
: 화면의 영역(레이아웃)을 잡아주는 엘리먼트
<View style={styles.container}></View>
Text
: 앱에 글을 작성하기 위해 반드시 사용해야하는 엘리먼트
<Text>Hello World!</Text>
ScrollView
: 앱 화면을 벗어나는 영역의 경우에 스크롤로 감싸서 모든 콘텐츠를 볼 수 있게 해주는 엘리먼트
- 태그 안에 있는 요소들이 스크롤바로 감싸진다.
<ScrollView style={styles.container}></ScrollView>
Button
: 버튼을 추가하는 엘리먼트
- 눌렀을 때 특정 이벤트가 일어나게 하려면 onPress에 함수를 연결해야 한다.
- 원하는 곳에 배치하기가 어렵고, 스타일링 주기가 어렵다.
<Button
title="Button"
onPress={() => alert("안녕하세요!")}
></Button>
TouchableOpacity
: 임의의 영역과 디자인에 버튼 기능을 달고 싶을 때 사용하는 엘리먼트
- Button 컴포넌트는 안드로이드와 iOS에서 다르게 보이기 때문에 관리하는데에 어려움이 있다.
- Button을 대체해 주로 사용한다.
const customAlert = () => {
alert("Hello World!");
};
return (
/* ... /*
<TouchableOpacity style={styles.container}>
<Text onPress={customAlert}>TouchableOpacity</Text>
</TouchableOpacity>
Image
: 이미지를 넣을 수 있는 엘리먼트
- 이미지를 넣는 방법은 두가지가 있다.
- assets 폴더에 있는 이미지를 가져와서 사용하는 방법 (import)
- 외부 이미지 링크를 넣어서 사용하는 방법 (url)
import favicon from "./assets/favicon.png";
/* . . . */
<Image
source={favicon}
resizeMode={"center"}
style={styles.imageStyle}
/>
<Image
source={{
uri: "https://images.unsplash.com/photo-1424819827928-55f0c8497861?fit=crop&w=600&h=600%27",
}}
resizeMode={"center"}
style={styles.imageStyle}
/>
styles 속성
- 태그에 스타일을 주는 방식 또한 리엑트 네이티브에서 제공하는 StyleSheet 기능을 가져와 적용한다.
- 모든 태그에 공통적으로 있는 style 속성에 아래에 만든 객체 키 값을 부여하여 적용한다.
- margin, padding 등의 속성이 자주 사용된다.
flex
: 영역의 레이아웃을 결정한다.
- flex
: 상대적으로 영역을 차지하는 속성
- 위치한 곳의 영역은 같은 레벨의 flex 합 비율대로 가져간다. - flexDirection
: 자리 잡은 영역의 방향을 결정하는 속성
- default값은 column
- row / column - justifyContent
: 영역 안에 있는 콘텐츠의 방향을 결정하는 속성
- 상위 엘리먼트에 적용을 해야 안에 있는 컨텐츠에 영향이 간다.
- flex-start / center / flex-end / space-between / space-around - alignItems
: flexDirection과 수직한 방향 (반대 방향)으로 정렬하는 속성
- flexDirection:"column" 에서 alignItems는 좌우 정렬을 뜻한다.
- flexDirection:"row" 에서 alignItems는 상하 정렬을 뜻한다.
- 상위 엘리먼트에 적용을 해야 안에 있는 컨텐츠에 영향이 간다.
- flex-start / center / flex-end / space-between / space-around
앱 화면 만들기 - 메인화면 꾸미기
▼ myapp/App.js
import React from "react";
import {
StyleSheet,
Text,
View,
Image,
ScrollView,
TouchableOpacity,
} from "react-native";
export default function App() {
return (
<ScrollView>
<Text style={styles.title}>나만의 꿀팁</Text>
<Image
source={{
uri: "https://firebasestorage.googleapis.com/v0/b/sparta-image.appspot.com/o/lecture%2Fmain.png?alt=media&token=8e5eb78d-19ee-4359-9209-347d125b322c",
}}
style={styles.mainImage}
resizeMode={"contain"}
/>
<ScrollView style={styles.middleContainer} horizontal>
<TouchableOpacity style={styles.middleButton}>
<Text style={styles.middleButtonText}>미용</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.middleButton}>
<Text style={styles.middleButtonText}>제테크</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.middleButton}>
<Text style={styles.middleButtonText}>할인</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.middleButton}>
<Text style={styles.middleButtonText}>기타</Text>
</TouchableOpacity>
</ScrollView>
<View style={styles.cardContainer}>
<View style={styles.card}>
<Image
style={styles.cardImage}
source={{
uri: "https://firebasestorage.googleapis.com/v0/b/sparta-image.appspot.com/o/lecture%2Fpizza.png?alt=media&token=1a099927-d818-45d4-b48a-7906fd0d2ad3",
}}
resizeMode={"center"}
/>
<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>
</View>
</View>
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
title: {
marginTop: "10%",
marginLeft: "5%",
fontSize: "25px",
fontWeight: "bold",
},
mainImage: {
height: 200,
width: "90%",
borderRadius: 10,
marginTop: 20,
alignSelf: "center",
},
middleContainer: {
margin: 10,
},
middleButton: {
width: 100,
height: 50,
padding: 15,
backgroundColor: "#fdc453",
borderColor: "deeppink",
borderRadius: 15,
margin: 7,
},
middleButtonText: {
textAlign: "center",
},
cardContainer: {
margin: 10,
},
card: {
flexDirection: "row",
},
cardImage: {
flex: 1,
width: 90,
height: 90,
borderRadius: 10,
},
cardText: {
flex: 2,
marginLeft: 10,
},
cardTitle: {
fontWeight: "bold",
fontSize: 20,
},
cardDesc: { fontSize: 15 },
cardDate: {
fontSize: 10,
},
});
앱&자바스크립트 - 모듈, 반복문, 조건식
모듈 시스템
: 여러 자바스크립트 파일이 있을 경우, 사로 다른 자바스크립트 파일에서 각 파일에 있는 함수를 불러오거나, 자바스크립트 파일 자체를 불러와 사용하는 것
- 여러 앱 파일을 만들 때, export default function 으로 함수를 내보낸다.
반복문 사용하기 - map
▽ idx, category,title,image,desc,date 프로퍼티가 있는 객체가 저장되어 있는 data.json 파일이 있다.
▼ myapp/App.js
- map으로 data.json에 있는 데이터를 가져와 화면에 표시한다.
import data from "./data.json";
let tip = data.tip;
/* ... */
{tip.map((content, i) => {
return (
<View style={styles.card} key={i}>
<Image
style={styles.cardImage}
source={{
uri: content.image,
}}
resizeMode={"center"}
/>
<View style={styles.cardText}>
<Text style={styles.cardTitle}>{content.title}</Text>
<Text style={styles.cardDesc} numberOfLines={3}>
{content.desc}
</Text>
<Text style={styles.cardDate}>{content.date}</Text>
</View>
</View>
);
})}
조건문 사용하기 - 삼항연산자
- 선택 사항이 두가지 뿐이라면, if문 보다는 삼항 연산자를 사용한다.
▼ myapp/App.js
- card가 짝수번째일때와 홀수번째일때의 이미지 위치를 다르게 설정한다.
{tip.map((content, i) => {
return i % 2 === 0 ? (
<View style={styles.card} key={i}>
<Image
style={styles.cardImage}
source={{
uri: content.image,
}}
resizeMode={"center"}
/>
<View style={styles.cardText}>
<Text style={styles.cardTitle}>{content.title}</Text>
<Text style={styles.cardDesc} numberOfLines={3}>
{content.desc}
</Text>
<Text style={styles.cardDate}>{content.date} 작성</Text>
</View>
</View>
) : (
<View style={styles.card} key={i}>
<View style={styles.cardText}>
<Text style={styles.cardTitle}>{content.title}</Text>
<Text style={styles.cardDesc} numberOfLines={3}>
{content.desc}
</Text>
<Text style={styles.cardDate}>{content.date} 작성</Text>
</View>
<Image
style={styles.cardImage}
source={{
uri: content.image,
}}
resizeMode={"center"}
/>
</View>
);
})}
2주차 숙제 - about 화면 만들기
▼ myapp/pages/AboutPage.js
import { StyleSheet, Text, Image, View, TouchableOpacity } from "react-native";
export default function AboutPage() {
return (
<View style={styles.container}>
<Text style={styles.mainText}>
HI! 스파르타코딩 앱개발{"\n"}반에 오신것을 환영합니다
</Text>
<View style={styles.middleContainer}>
<Image
style={styles.aboutImage}
source={{
uri: "https://storage.googleapis.com/sparta-image.appspot.com/lecture/about.png",
}}
/>
<Text style={styles.midderTextOne}>
많은 내용을 간결하게 담아내려{"\n"}노력했습니다!
</Text>
<Text style={styles.middleTextTwo}>
꼭 완주 하셔서 꼭 여러분것으로 만들어가시길{"\n"}바랍니다
</Text>
<TouchableOpacity style={styles.middleButton}>
<Text style={styles.middleButtonText}>여러분의 인스타계정</Text>
</TouchableOpacity>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#1F266A",
},
mainText: {
margin: 30,
marginTop: 70,
textAlign: "center",
color: "white",
fontSize: 30,
fontWeight: "bold",
},
middleContainer: {
alignSelf: "center",
width: "80%",
height: "60%",
backgroundColor: "white",
borderRadius: 20,
alignItems: "center",
justifyContent: "center",
},
aboutImage: {
borderRadius: 30,
width: 150,
height: 150,
},
midderTextOne: {
margin: 15,
textAlign: "center",
fontSize: 20,
fontWeight: "bold",
},
middleTextTwo: {
margin: 10,
textAlign: "center",
fontSize: 15,
fontWeight: "bold",
},
middleButton: {
margin: 10,
width: 150,
height: 50,
backgroundColor: "orange",
justifyContent: "center",
borderRadius: 10,
},
middleButtonText: {
fontSize: 15,
textAlign: "center",
fontWeight: "bold",
color: "white",
},
});
'FRONTEND > React Native' 카테고리의 다른 글
[React Native] 웹뷰 제작 (feat. expo) (0) | 2023.12.25 |
---|---|
[ REACT NATIVE ] 나만의 수익성 앱 개발 5주차 학습노트 (1) | 2023.03.05 |
[ REACT NATIVE ] 나만의 수익성 앱 개발 4주차 학습노트 (0) | 2023.02.26 |
[ REACT NATIVE ] 나만의 수익성 앱 개발 3주차 학습노트 - ② (0) | 2023.02.25 |
[ REACT NATIVE ] 나만의 수익성 앱 개발 3주차 학습노트 - ① (0) | 2023.02.24 |