[Sparta] 앱개발 2주차

HAM·2022년 12월 23일
1

[Sparta] 앱 개발

목록 보기
2/3
post-thumbnail

리액트 네이티브 앱 개발의 장점

  • 페이스북에서 만든 언어
  • 자바스크립트만으로 안드로이드 앱과 ios앱 모두 만들어주는 라이브러리
  • EXPO 도구 사용

리액트 네이티브 = 리액트(React) + 네이티브(Native)

EXPO 도구
1) 안드로이드 & iOS 코드를 몰라도 개발이 가능
-> 조금 더 쉽게 리액트 네이티브를 만질 수 있음
2) 개발 중인 앱을 쉽게 확인해주는 앱 제공
-> https://expo.io/signup Expo 가입 & 폰에서도 EXPO앱 다운
3) Node & NPM 설치

  • Node와 NPM
    -> Node.js로 자바스크립트 개발 환경 구축, NPM으로 필요한 자바스크립트 앱 개발 도구를 가져와 사용함
  • Yarm
    -> 맥은 terminal에서 설치
	sudo npm install -g yarn
![](https://velog.velcdn.com/images/hamzzi/post/8dcfb7bd-0cdb-47ab-9d60-442885f2c11f/image.png)

4) EXPO 명령어 도구 설치

```
sudo npm install -g expo-cli
```
![](https://velog.velcdn.com/images/hamzzi/post/81558250-8f76-44bb-9c49-751954cd972e/image.png)
![](https://velog.velcdn.com/images/hamzzi/post/6cf1eeff-9ba2-4453-9b1a-f2398ed7f062/image.png)

안된다면
```
sudo npm install --unsafe-perm -g expo-cli
```

5) Expo가입 및 로컬에 Expo 계정 세팅

  • 순수 리액트 네이티브로 해도 안드로이드와 iOS 코드를 건들여야 되는데 그러지 않게 해줌
  • 추후 앱 관리와 배포를 한 번에 진행 할 수 있음
    -> https://expo.io/signup Expo 가입 후 터미널에서 계정 연결
    expo login

가입한 이메일 주소와 비밀번호 입력하라고 뜨고 다 작성하면

완료!
6) Expo 앱 생성 및 실행하기

    expo init sparta-myhoneytip-ham


그냥 blank로 설정해서 만듬

expo start

터미널에서 실행을 시키면 되는데

앱 생성한 파일(sparta-myhoneytip-ham)에서 실행시키지 않으면 위와 같은 오류가 뜬다

제대로 들어가서 치면 위와 같은 QR코드가 뜨는데 휴대폰에 다운 받은 앱(Expo Go)로 들어가서 볼 수 있다

확인!
7) Expo프로젝트 기본 폴더 구조

> asset	폴더
앱이 가질 수 있는 이미지(리소스)
> node_modules
개발자들이 만든 자바스크립트 도구들이 모여있는 도구함
다운 받은 도구들이 다 들어가 있음
> App.js
도입부
>app.json
디스크립션, 사용 설명서, 앱이 가지는 기본 정보들을 설정하는 파일

8) App.js 구석구석 살펴보기
- import 해서 필요한 것들 꺼내오기
- export default 화면에 앱 띄우기 위한 것
- 분할해서 쓴 옆에 휴대폰 화면은 QuickTime Player을 사용

- textStyle을 만들어서 글씨 색을 green으로 바꾼 것을 확인

- 가끔 밑에 경고창이 뜰 수 있는데 안 보게 하려면 코드 작성

9) 화면을 구성하는 태그 문법, JSX
- 리액트 네이티브에서 return은 작성한 JSX문법으로 구성된 화면을 앱상에 보여주는 역할
->JSX문법을 화면에 그려준다는 행위, 동작을 렌더링(rendering)이라고 함
- < > 꺽쇠로 이루어져 있음
- 모든 태그는 가져와서 사용함 (import) 사용
공식 문서 확인
https://reactnative.dev/docs/view?redirected
- 태그는 항상 닫는 태그와 자체적으로 닫는 태그를 구분해서 사용해야 함
- 모든 엘리먼트는 감싸는 최상위 엘리먼트가 있어야함 (엘리먼트 = 태그 = <>)
- return에 의해 렌더링 될 땐 항상 소괄호()로 감싸져야 함
- JSX 문법 밖에서의 주석//과 안에서의 주석/**/은 다름

10) 앱 화면 만들기 : View, Text, ScrollView

  • <View></View>
    화면의 영역(레이아웃)을 잡아주는 엘리먼트
    화면을 원하는 대로 분할 할 수 있음

  • <Text>
    문자는 텍스트 태그 안에 작성!
  • <ScrollView>
    앱 화면을 벗어나는 영역의 경우 스크롤이 가능해지면서 모든 컨텐츠를 볼 수 있음


    위와 같이 View 태그로는 스크롤이 불가능함


    ScrollView 태그를 사용해야지 스크롤이 가능!

11) 앱 화면 만들기 : Button, Image

  • <Button>과 함수
    • SafeAreaView 를 사용해서 아이폰의 대머리 부분에 컨텐츠가 가려지지 않게 함


      - /> 바로 닫힘
      - 버튼을 누르면 다음과 같은 팝업창이 뜸
      - 화살표 함수(=>)로 팝업창을 연결 할 수 있음
      - 공식문서 확인
      버튼 설명서
      https://reactnative.dev/docs/button
      팝업 알람(Alert) 설명서
      https://reactnative.dev/docs/alert#docsNav
    • OnPress

      - 바로 함수를 연결 시키려면 소괄호가 없음
      • 원래 부르던 방식대로 부르려면 함수를 사용하는 거니까 소괄호 필요
  • <TouchableOpacity/>
    - Button 태그보다 스타일에 있어 자유도가 높음
    • 꾸미기에 더 좋은 태그이기 때문에 이 태그를 주로 사용
  • Image
    - assets 폴더 안에 있는 이미지 사용


    - 외부 이미지 사용

12) 구성한 화면 꾸미기, Styles

13) 콘텐츠의 위치 : Flex

  • 영역의 레이아웃을 결정

    - 빨강은 화면 전체의 영역에서 3/1, 노랑은 3/2 영역을 차지하는 함 (상대적, 합의 개념)

    - 노란색이 보이지 않지만 영역을 차지하고 있다는 것!
  • flexDirection

    - 달라진 것은 정렬을 바꾼 것 (row)
  • justifyContent
    - flexDirection과 동일한 방향으로 정렬하는 속성

    - 달라진 것은 innerTwo 코드를 확인!

    - justifyContent를 center로 바꾸면 글씨가 가운데로 온다는 것을 확인
  • alignItems
    - justifyContent의 반대 방향으로 정렬하는 속성

14) 메인화면 꾸미기
- 글씨 위치를 조절하는 것부터 어려웠음
15) 메인화면 완성

import React from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity, ScrollView} from 'react-native';

const main = 'https://firebasestorage.googleapis.com/v0/b/sparta-image.appspot.com/o/lecture%2Fmain.png?alt=media&token=8e5eb78d-19ee-4359-9209-347d125b322c'

export default function App() {
  return (
    <ScrollView style={styles.container}>
      <Text style={styles.title}>나만의 꿀팁</Text>
      <Image style={styles.mainImage} source={{uri:main}}/>
      <ScrollView style={styles.middleContainer} horizontal indicatorStyle={"white"}>
        <TouchableOpacity style={styles.middleButton01}><Text style={styles.middleButtonText}>생활</Text></TouchableOpacity>
        <TouchableOpacity style={styles.middleButton02}><Text style={styles.middleButtonText}>재테크</Text></TouchableOpacity>
        <TouchableOpacity style={styles.middleButton03}><Text style={styles.middleButtonText}>반려견</Text></TouchableOpacity>
        <TouchableOpacity style={styles.middleButton04}><Text style={styles.middleButtonText}>꿀팁 찜</Text></TouchableOpacity>
      </ScrollView>
      <View style={styles.cardContainer}>
        {/* 하나의 카드 영역을 나타내는 View */}
        <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"}}/>
          <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: {
    //앱의 배경 색
    backgroundColor: '#fff',
  },
  title: {
    //폰트 사이즈
    fontSize: 20,
    //폰트 두께
    fontWeight: '700',
    //위 공간으로 부터 이격
    marginTop:50,
	    //왼쪽 공간으로 부터 이격'
    marginLeft:20
  },
  mainImage: {
    //컨텐츠의 넓이 값
    width:'90%',
    //컨텐츠의 높이 값
    height:200,
    //컨텐츠의 모서리 구부리기
    borderRadius:10,
    marginTop:20,
    //컨텐츠 자체가 앱에서 어떤 곳에 위치시킬지 결정(정렬기능)
    //각 속성의 값들은 공식문서에 고대로~ 나와 있음
    alignSelf:"center"
  },
  middleContainer:{
    marginTop:20,
    marginLeft:10,
    height:60
  },
  middleButton01: {
    width:100,
    height:50,
    padding:15,
    backgroundColor:"#fdc453",
    borderColor:"deeppink",
    borderRadius:15,
    margin:7
  },
  middleButton02: {
    width:100,
    height:50,
    padding:15,
    backgroundColor:"#fe8d6f",
    borderRadius:15,
    margin:7
  },
  middleButton03: {
    width:100,
    height:50,
    padding:15,
    backgroundColor:"#9adbc5",
    borderRadius:15,
    margin:7
  },
  middleButton04: {
    width:100,
    height:50,
    padding:15,
    backgroundColor:"#f886a8",
    borderRadius:15,
    margin:7
  },
  middleButtonText: {
    color:"#fff",
    fontWeight:"700",
    //텍스트의 현재 위치에서의 정렬 
    textAlign:"center"
  },
  cardContainer: {
    marginTop:10,
    marginLeft:10
  },
  card:{
    flex:1,
    //컨텐츠들을 가로로 나열
    //세로로 나열은 column <- 디폴트 값임 
    flexDirection:"row",
    margin:10,
    borderBottomWidth:0.5,
    borderBottomColor:"#eee",
    paddingBottom:10

  },
  cardImage: {
    flex:1,
    width:100,
    height:100,
    borderRadius:10,
  },
  cardText: {
    flex:2,
    flexDirection:"column",
    marginLeft:10,
  },
  cardTitle: {
    fontSize:20,
    fontWeight:"700"
  },
  cardDesc: {
    fontSize:15
  },
  cardDate: {
    fontSize:10,
    color:"#A6A6A6",
  }


});

완성된 코드를 보고 다시 공부하기..

- horizontal을 통해서 스크롤 방향 바꿈 (가로로)
- numverOfLines를 통해서 피자 글을 세줄만 나타내게 함
- 전체적인 레이아웃을 구성하는 경우에는 무조건 < View >로 하기

16) 모듈과 반복문

  • 모듈 시스템(module system)
    여러 자바스크립트 파일이 있을 경우, 서로 다른 자바스크립트 파일에서 각 파일에 있는 함수를 불러오거나, 자바스크립트 파일 자체를 불러올 때 사용함
//A.js 파일
//times, plusTwo 함수를 외부로 내보낼 준비를 합니다.
export function times(x) {
  return x * x;
}
export function plusTwo(number) {
  return number + 2;
}

//B.js 파일
//다른 자바스크립트 파일에서 다음과 같이 불러와 사용합니다.
import { times, plusTwo } from './util.js';
console.log(times(2));
console.log(plusTwo(3));


- data.json 이라는 파일을 만들어서 작성 후 App.js 파일에 임포트 시킴

  • map 사용


    - 반복적인 태그를 돌려서 화면에 나타내는 경우에 고유한 key 값이 필요함

17) {} 표현식과 조건문

  • 선택 사항이 두 가지 뿐이라면 if, else 보다는 삼항 연사자를 사용하는 것이 좋음
let result = 10 > 2 ? "참" : "거짓"

(기본 모습)
let result = 조건 ? 참일 때 : 거짓 일때

(예제)
let result = 10 == 9 ? true : false  // result <-- false 값 할당  
let result = 10 !== 9 ? true : false // result <-- true  할당  
let reuslt = 99 > 10 ? true : false // result <-- true 값 할당  


- 나눗셈의 결과가 짝수이면 노란색 홀수라면 흰색이 됨

2주차 너모 어렵다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
복붙이 제일 쉬웠다.....
숙제 내주신 것은.. 이 밑에 차근차근 하겠어요.

숙제

  • 초반 세팅 미리 해두기
    - pages 폴더 만들고 MainPage.js에는 App.js에서 만든 코드를 넣고 AboutPage.js는 기본 세팅을 해두고 숙제 시작
import React from 'react'
import { StyleSheet, Text, View, Image, TouchableOpacity, ScrollView} from 'react-native';

export default function AboutPage(){
    const aboutImage = "https://storage.googleapis.com/sparta-image.appspot.com/lecture/about.png"
  return (
    <View style={styles.container}>
        <Text style={styles.title}>HI! 스파르타코딩 앱 개발반에 오신것을 환영합니다 </Text>
        
        {/* 둥근 사각형 부분 */}
        <View style={styles.textContainer}>
            <Image style={styles.aboutImage} source={{uri:aboutImage}} resizeMode={"cover"}/>
            <Text style={styles.middleTitle}>많은 내용을 간결하게 담아내려 노력했습니다!</Text>
            <Text style={styles.middleText}>꼭 완주 하셔서 꼭 여러분 것으로 만들어가시길 바랍니다</Text>

            <TouchableOpacity style={styles.Button}>
                <Text style={styles.ButtonText}>여러분의 인스타계정</Text>
            </TouchableOpacity>
        </View>
  </View>
  )
}

const styles = StyleSheet.create({
    container: {
        //flex가 1이면 전체로 설정됨
        flex:1,
        //앱의 배경 색
        backgroundColor: '#006',
    },
    title: {
        //폰트 사이즈
        fontSize: 35,
        //폰트 두께
        fontWeight: '700',
        //위 공간으로 부터 이격
        marginTop:120,
        //왼쪽 공간으로 부터 이격
        marginLeft:50,
        marginRight:50,
        color: '#fff',
      },
      textContainer: {
        //컨텐츠의 넓이 값
        width:300,
        //컨텐츠의 높이 값
        height:500,
        //컨텐츠의 모서리 구부리기
        borderRadius:10,
        marginTop:20,
        //컨텐츠 자체가 앱에서 어떤 곳에 위치시킬지 결정(정렬기능)
        //각 속성의 값들은 공식문서에 고대로~ 나와 있음
        alignSelf:"center",
        //textContainer의 배경색 설정
        backgroundColor:'#fff'
      },
      aboutImage: {
        width:150,
        height:150,
        borderRadius:30,
        marginTop:70,
        marginLeft:80,
        marginRight:80
      },
      middleTitle: {
        //폰트 사이즈
        fontSize: 25,
        //폰트 두께
        fontWeight: '700',
        //위 공간으로 부터 이격
        marginTop:10,
        //왼쪽 공간으로 부터 이격
        marginLeft:20,
        marginRight:20,
        textAlign:'center'
      },
      middleText: {
        //폰트 사이즈
        fontSize: 20,
        //폰트 두께
        fontWeight: '700',
        //위 공간으로 부터 이격
        marginTop:20,
        //왼쪽 공간으로 부터 이격
        marginLeft:10,
        marginRight:10,
        textAlign:'center'
      },
      Button: {
        width:150,
        height:55,
        padding:10,
        marginLeft:75,
        marginTop:20,
        backgroundColor:"#fdc453",
        borderColor:"deeppink",
        borderRadius:15,
      },
      ButtonText: {
        //폰트 사이즈
        fontSize: 17,
        //폰트 두께
        fontWeight: '700',
        //위 공간으로 부터 이격
        marginTop:10,
        textAlign:'center',
        color:'#fff'
      }
})


막상 해봤는데 비슷하지 않나? 아니 똑같지 않나?!
했던 코드들 사용해서 막 했더니 주석이 그대로 붙어 있어서 깔끔하지 못한 코드지만 뿌듯합니당 :-) ~~!!

2주차까지 마무리 완!

profile
Frontend developer

0개의 댓글