스파르타 코딩 클럽 내일 배움단 - 앱개발 2주차

스파르타 코딩 클럽 내일 배움단 3일차 일지

오늘 새벽에 웹개발을 마무리하고 잠든 뒤에 일어나서 발로 앱개발 공부를 시작했다.

웹개발에서는 HTML, CSS, JS 기초 배우고 있는데 여기서는 JS 프레임워크 배우고 있으니 약간 헷갈린다 ㅠㅠ.

힘들지만 열심히 해야 취업하겟지...?

 

 

학습 내용

1. React Native & Expo 실행하기

2. JSX 문법

3. 화면을 구성하는 엘리먼트

4. 메인화면 만들어보기

5. 모듈, 반복문, {}표현식, 조건문

 

 

1. React Native & Expo 실행하기

React Native란 ?

React + Native의 합성어로 웹프론트 프레임워크인 React를 사용하여 웹앱을 만드는 도구입니다.

JavaScript 언어 하나로 안드와 iOS에서 호환되는 멀티플랫폼 앱을 만들 수 있다는 장점이 있습니다.

하지만 특정 상황에서는 안드로이드와 iOS에서 별도로 코드 작업을 해야 한다는 큰 단점이 있었는데,

Expo라는 도구가 그 단점을 커버해줍니다.


Expo란?

React Native에서 별도의 코드작업의 필요성을 없애주는 도구입니다.

그리고 안드, iOS에서 테스트하기 위한 클라이언트 앱을 제공해줍니다.

 

1. Node & NPM 설치

Node.js를 사용해 자바스크립트 개발환경을 만들고, NPM을 통해 자바스크립트 앱 개발 도구들을 가져옵니다.

 

2. Yarn

yarn은 npm보다 가볍고 빠르게 자바스크립트 패키지를 관리 할 수 있게 해주는 자바스크립트 패키지 매니저 툴입니다.

npm install -g yarn
yarn -v

 

3. Expo 설치

Expo는 npm으로 설치합니다.

npm install -g expo-cli

 

4. Expo 가입

사이트에 들어가서 회원가입을 진행합니다

https://expo.dev/

 

Expo

Expo is an open-source platform for making universal native apps for Android, iOS, and the web with JavaScript and React.

expo.dev

 

5. PC에서 Expo 로그인

cmd 혹은 terminal을 열고 명령어를 칩니다.

expo login --username "<Expo Username>"

<Expo Username> 부분에는 엑스포에 가입할 때 입력했던 Username을 입력해주면 됩니다.

 

6. Expo 프로젝트 생성

expo init <프로젝트명>

 

7. Expo 프로젝트 실행

Expo 프로젝트 폴더로 이동해서 아래 명령어를 친다

expo start

그러면 나오는 페이지에서 보이는 QR 코드를 폰으로 스캔하면 모바일에서 확인할 수 있다...!

 

모바일 화면

 

2. JSX 문법 알아보기

//우리가 리액트, 리액트 네이티브, 엑스포 라이브러리에서 꺼내 사용할 기능들을
//이렇게 앞으로도 상단에 선언한다음 가져다 사용합니다.
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

//App.js는 결국 App 함수를 내보내기 하고 있는 자바스크립트 파일입니다.
//이 함수는 무언가?를 반환하고 있는데 결국 화면을 반환하고 있습니다.
export default function App() {
	//화면을 반환합니다.
	//HTML 태그 같이 생긴 이 문법은 JSX라 불리우며 실제 화면을 그리는 문법입니다,
	//이번 강의에서 자세히 다룹니다
	console.disableYellowBox = true; // 경고 메세지 없애기
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
      <StatusBar style="auto" />
    </View>
  );
}

// styles 변수 이름 답게 화면을 그려주는, 
//더 자세히는 JSX문법을 꾸며주는 내용을 담고 있습니다.
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

 

JSX 기본 문법

1. 모든 태그는 가져와서 사용함

아래에서 <View> 태그와 <Text> 태그는 위에 import 부분을 잘 보면 Text, View 가 있는 것을 볼 수 있습니다.

이것은 이 태그들이 'react-native'라고 하는 도구에서 가져와서 사용하는 태그라는 뜻이므로 우리가 화면을 그릴 때

필요한 태그들을 리액트 네이티브 공식 문서에서 참고해서 사용합니다.

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
    </View>
  );
}

 

 

공식 문서 - https://reactnative.dev/docs/view

 

View · React Native

The most fundamental component for building a UI, View is a container that supports layout with flexbox, style, some touch handling, and accessibility controls. View maps directly to the native view equivalent on whatever platform React Native is running o

reactnative.dev

 

2. 태그는 항상 닫는 태그와 자체적으로 닫는 태그를 구분해서 사용해야 함

export default function App() {
  return (
	//<View>는 결국 두번째 줄 밑에 </View>로 닫히면서 본인 영역을 갖습니다 
    <View style={styles.container}>
        <Text>Open up App.js to start working on your app!</Text>
        //statusBar는 본인 스스로 닫는 태그이므로 다음과 같이 사용이 가능합니다.
        <StatusBar style="auto" />
    </View>
  );
}

 

3. 모든 엘리먼트는 감싸는 상위 엘리먼트가 필요함

//App.js가 렌더링 하고 엘리먼트는 결국
//Text와 StatusBar엘리먼트를 감싸고 잇는 View입니다.
export default function App() {
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
      <StatusBar style="auto" />
    </View>
  );
}

 

4. return에는 무조건 소괄호를 써야 함

 

5. JSX 문법 밖에서의 주석과 안에서의 주석이 틀림

//JSX밖에서의 주석
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
//JSX밖에서의 주석
export default function App() {
	//JSX밖에서의 주석
  return (
		//JSX 밖에서의 주석
    <View style={styles.container}>
			{/*
				JSX 문법 안에서의 주석
			*/}
      <Text>Open up App.js to start working on your app!</Text>
      <StatusBar style="auto" />
    </View>
  );
}

//JSX밖에서의 주석
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

 

3. 화면을 구성하는 기본 엘리먼트

<View> : 화면의 영역을 잡아주는 엘리먼트

<Text> : 글을 표현하는 엘리먼트

<ScrollView> : 스크롤 할 수 있는 <View> 엘리먼트

<Button> : 버튼 엘리먼트

( <Button> 사용 예 )

import React from 'react';
import { StyleSheet, Text, View, Button, Alert } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <View style={styles.textContainer}>
        <Text style={styles.textStyle}>아래 버튼을 눌러주세요</Text>
        {/* ES6 문법으로 배웠던 화살표 함수로 연결 할 수도 있습니다. */}
        <Button 
            style={styles.buttonStyle} 
            title="버튼입니다 "
            color="#FF0000" 
            onPress={()=>{
              Alert.alert('팝업 알람입니다!!')
            }}
          />
          </View>
    </View>
  );
}

<TouchableOpacity/> : 버튼이지만 버튼과는 달리 아무런 디자인이 없는 버튼이라고 보면 된다. 안에 다른 엘리먼트를 집어 넣을 수 있다.

<Image> : 이미지를 출력하는 엘리먼트

 

 

태그에 스타일 넣기

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

export default function App() {
  return (
    <View style={styles.container}>
      <View style={styles.textContainer}>
        <Text style={styles.textStyle}>스파르타 코딩클럽!!</Text>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    //영역을 잡는 속성입니다. 따로 자세히 다룹니다.
    //flex: 1은 전체 화면을 가져간다는 뜻입니다
    flex: 1,
    //영역의 배경 색을 결정합니다
    backgroundColor: '#fff',
    //아래 두 속성은 영역 안의 컨텐츠들의 배치를 결정합니다. 
    //flex를 자세히 다룰때 같이 자세히 다룹니다
    justifyContent:"center",
    alignContent:"center"
  },
  textContainer: {
    //영역의 바깥 공간 이격을 뜻합니다(하단 이미지 참조)
    margin:10,
    //영역 안의 컨텐츠 이격 공간을 뜻합니다(하단 이미지 참조)
    padding: 10,
    //테두리의 구부러짐을 결정합니다. 지금 보면 조금 둥글죠?
    borderRadius:10,
    //테두리의 두께를 결정합니다
    borderWidth:2,
    //테두리 색을 결정합니다
    borderColor:"#000",
    //테구리 스타일을 결정합니다. 실선은 solid 입니다
    borderStyle:"dotted",

  },
  textStyle: {
    //글자 색을 결정합니다. rgb, 값 이름, 색상코드 모두 가능합니다
    color:"red",
    //글자의 크기를 결정합니다
    fontSize:20,
    //글자의 두께를 결정합니다
    fontWeight:"700",
    //가로기준으로 글자의 위치를 결정합니다
    textAlign:"center"
  }
});

 

4. 메인 화면 완성하기

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 (
    <ScrollView style={styles.container}>
      <Text style={styles.title}>나만의 꿀팁</Text>
      <Image style={styles.mainImage} source={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",
  }


});

 

5. 모듈, 반복문, {} 표현식, 조건문

 

모듈

//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));

 

반복문

  return (
    /*
      return 구문 안에서는 {슬래시 + * 방식으로 주석
    */
    <ScrollView style={styles.container}>
      <View style={styles.cardContainer}>
         {/* 하나의 카드 영역을 나타내는 View */}
         { 
          tip.map((content,i)=>{
            return (<View style={styles.card} 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>
    </ScrollView>
  );
}

 

{} 표현식

JSX 문법 사이에 {} 를 사용함으로써 javascript 문법을 사용할 수 있다.

 

조건문

짝수개마다 다르게 표시하는 코드

return (
    /*
      return 구문 안에서는 {슬래시 + * 방식으로 주석
    */
    <ScrollView style={styles.container}>
      <View style={styles.cardContainer}>
         {/* 하나의 카드 영역을 나타내는 View */}
         { 
          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>)

          })
         }
      </View>
    </ScrollView>
);

 

6. 2주차 숙제

어바웃 화면 만들기

 

작성코드 (틀릴수도 있음)

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

const centerImage = 'https://firebasestorage.googleapis.com/v0/b/sparta-image.appspot.com/o/lecture%2FaboutImage.png?alt=media&token=13e1c4f6-b802-4975-9773-e305fc7475c4'


export default function MainPage() {
    LogBox.ignoreAllLogs();
    return (
        <ScrollView style={styles.container}>
            <View style={styles.wrap}>
                <Text style={styles.mainText}>Hi! 스파르타코딩 앱개발반에 오신것을 환영합니다</Text>
                <View style={styles.box}>
                    <Image style={styles.centerImage} source={{url:centerImage}}/>
                    <Text style={styles.topText}>많은 내용을 간결하게 담아내려 노력했습니다!</Text>
                    <Text style={styles.contentText}>꼭 완주 하셔서 꼭 여러분 것으로 만들어가시길 바랍니다</Text>
                    <View style={styles.btn}>
                        <Text style={styles.btnText}>여러분의 인스타계정</Text>
                    </View>
                </View>
            </View>
        </ScrollView>
    )
}

const styles = StyleSheet.create({
    container: {
        backgroundColor: "#334499",
    },
    wrap: {
        width: "80%",
        alignSelf: "center"
    },
    mainText: {
        marginTop: 100,
        fontSize: 30,
        color: "#f0f0f0",
        fontWeight: "bold"
    },
    box: {
        width: "100%",
        height: 500,
        backgroundColor: "#fff",
        borderRadius: 30,
        marginTop: 40
    },
    centerImage: {
        width: 150,
        height: 150,
        borderRadius: 20,
        alignSelf: "center",
        marginTop: 70,
    },
    topText: {
        width: "80%",
        fontSize: 24,
        fontWeight: "600",
        alignSelf: "center",
        textAlign: "center"
    },
    contentText: {
        width: "80%",
        fontSize: 16,
        marginTop: 20,
        alignSelf: "center",
    },
    btn: {
        width: "50%",
        height: 50,
        backgroundColor: "#eb832a",
        alignSelf: "center",
        marginTop: 30,
        borderRadius: 15,
    },
    btnText: {
        fontWeight: "600",
        color: "#fff",
        textAlign: "center",
        lineHeight: 50,
        fontSize: 12,
    }
})

 

+ Recent posts