spartaCodingClub 2주차 개발일지

2주 차 핵심 내용 정리 📝

[목차]

1) EXPO 및 simulator 실행법
2) 기본적으로 필요한 코드 및 노란색 경고창 없애는 법
3) StatusBar
4) JSX 기본 문법
5) Flex
6) Map
7) 삼항 연산자

1) EXPO 및 simulator 실행법

앱 개발할 폴더에 들어간 후 터미널 오픈


(이미지 출처 : 스파르타 코딩 클럽)

터미널을 열었으면 다음과 같은 명령어 입력
expo init 폴더명

expo 는 Expo 명령어를 사용하겠다는 의미
init 은 Expo 앱을 생성하는 Expo 명령어
폴더명은 원하는 앱 이름 작성


(이미지 출처 : 스파르타 코딩 클럽)

명령어 입력 다하면 위의 사진과 같은 문구가 나타나는데 'blank' 선택

1-1) ios simulator 실행법

터미널에 cd 폴더명(앱 개발할 폴더명)을 입력하여 접속 후

1) expo start —ios
2) shift + i
3) 방향키로 ios 버전 선택
4) enter

2) 기본적으로 필요한 코드

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

2-1) 노란색 경고창 없애는 법

경고창 모습


(이미지 출처 : 스파르타 코딩 클럽)

LogBox 속성 사용(💡)

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View, LogBox } from 'react-native';
                            // HERE 💡

export default function App() {

	LogBox.ignoreLogs(['Warning: ...']); //HERE 💡
    
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

3) StatusBar

불러오는 법(💡)

import { StatusBar } from 'expo-status-bar'; //HERE 💡
import { StyleSheet, 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>
      <StatusBar style="light" /> //HERE 💡
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

결과값

StatusBar 는 휴대폰 상단의 바를 뜻하며

‘light’ 를 입력하면 위의 사진처럼 흰색으로 변해 사라지는 것을 볼 수가 있다.

반대로 ‘dark’ 를 입력하면 검정색으로 변해 다시 나타난다.

4) JSX 기본 문법

🔠 항상 대문자로 시작해야 한다.

ex)

<<View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
      <StatusBar style="light" />
    </View>
😁 JSX 문법을 화면에 그려준다는 행위, 동작을 렌더링(rendering) 이라 부른다.

App.js는 JSX문법으로 그려져 준비된 화면을 반환한다.
반환 한다는 게 잘 와닿지 않다면, 단순히 화면을 그려준다 생각하면 편하다.
즉, 리액트 네이티브에서 return은 여러분이 작성한 JSX문법으로 구성된 화면을 앱상에 보여주는 역할을 한다.

👕 옷 입히기(style) - 예시 코드

 <View style={styles.container}>
    <Text style={styles.textStyle}>Hello World!</Text>
    <StatusBar style="light" />
 </View>

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  textStyle: {
    color: 'red'
  }
});

📄 모든 태그는 공식 문서에서 가져와야 한다.

View나 Text 같은 문법은 임의로 만든 태그들이 아니다. 
리액트 네이티브에서 제공해주는, 
이미 존재하는 태그 문법을 가져와서 사용하는 것. 

공식 문서

🔄 return 에 의해 렌더링 될 땐 항상 소괄호로 감싸져야 한다.

return 구문으로 엘리먼트를 렌더링(반환) 할 때 소괄호로 항상 감싸여 있다.

🤓 개발할 때 코멘트, 즉 주석을 남기는 법(💡)

//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',
  },
});

5) Flex

5-1) justifyContent

justifyContent 는 flexDirection 과 동일한 방향으로 정렬하는 속성이다.

flexDirection + ‘column’ + justifyContent = 상하 정렬
flexDirection + ‘row’ + justifyContent = 좌우 정렬

flex-start, center, flex-end, space-between, space-around 속성을 가진다.

ex)

//생략

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-end", 💡
    backgroundColor:"orange"
  }
});

결과값

containerTwo 의 flexDirection 을 ‘row’ 로 설정해서

containerTwo 안에 있는 요소(innerOne, innerTwo)들이 세로로 정렬되었다.

다음으로, innerTwo 의 justifyContent 값을 ‘flex-end’ 로 설정하였더니

텍스트가 왼쪽 하단에 위치한 모습을 볼 수 있다.

이는 innerTwo 의 flexDirection 이 기본값인 ‘column’ 으로 정의되어 있기 때문에

상하 정렬로 인한 결과값이라고 볼 수 있다.

🤔 그렇다면 innerTwo 의 flexDirection 을 ‘row’ 로 설정한다면 어떻게 될까?

//생략

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,
    flexDirection:"row", 💡
    justifyContent:"flex-end", 💡
    backgroundColor:"orange"
  }
});

결과값

위의 사진과 같이  innerTwo의 flexDirection을 ‘row’로 설정하면 
텍스트가 오른쪽 상단에 위치한 모습을 볼 수 있다. 
이는 앞서 말했듯이 innerTwo의  flexDirection을 ‘row’로 줌으로써 
justifyContent가 좌우 정렬 이 일어난 모습을 볼 수 있다.

5-2) alignItems

Align Items 는 Flex Direction 과 수직 한 방향(반대 방향이라고 생각하면 편하다.)

flexDirection + column + alignItems = 좌우 정렬
flexDirection + row + alignItems = 상하 정렬

flex-start, center, flex-end, stretch 속성을 가진다.

ex)

//생략

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",
    alignItems:"flex-end", 💡
  },
  content: {
    width:50,
    height:50,
    backgroundColor:"#000"
  }
});

결과값

위의 사진과 같이 ‘innerTwo’의 속성이 기본값인 ‘column’으로 정의되어 있으며

‘alignItems’는 ‘justifyContent’와 반대 개념을 가지고 있기 때문에

‘alignItems’ 를 사용하였을 때 ‘좌우 정렬’이 일어난 모습을 볼 수 있다.

6) Map

'Map' 함수란?

리스트 안에 있는 요소 하나하나를 끝날 때까지
순차적으로 검색해 보면서 그 값을 내뱉는 함수

❌ Map 함수를 사용 안 했을 때 - 예시 코드

//생략

<View style={styles.cardContainer}>
	<View style={styles.card}>
		<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>

const styles = StyleSheet.create({
//생략

  cardContainer: {
    marginTop: 10,
    marginLeft: 10
  },
  card: {
    flex: 1,
    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",
  },


});

⭕️ Map 함수를 사용했을 때 - 예시 코드

//생략
import data from './data.json';

export default function App() {
  let tip = data.tip;
  let todayWeather = 10 + 17;
  let todayCondition = "흐림"
  return (
    //생략
      <View style={styles.cardContainer}>
        {
          tip.map((content, i) => { /* 1 💡 */
            return (<View style={styles.card} key={i}> /* 2 💡 */
              <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>
  );
}

const styles = StyleSheet.create({
  //생략

  cardContainer: {
    marginTop: 10,
    marginLeft: 10
  },
  card: {
    flex: 1,
    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",
  },


});

[해석]
1. ‘content’ 라는 변수에 담아서 내뱉고 ‘i’ 라는 변수에 내 콘텐츠가
하나하나 요소의 순서를 담았다.

2. JSX 문법에서 여러가지 반복적인 태그를 돌려서 화면에 나타내는 경우에 반복적으로 나타내는 태그는 고유한 ‘key’ 값을 부여해 주어야 한다.
즉, 반복적으로 나타내는 태그마다 ‘이건 고유한 태그야’ 라고
알려줘야지 오류가 안 난다.

여기서 ‘i’ 란 ’map’ 함수로 리스트를 돌렸을 때
그 요소요소 하나에 순서(인덱싱)를 나타내는 값이

‘i’ 에 담게 되는 것을 말하고 이렇게 담아지게 되면
카드에 고유한 번호를 부여할 수 있게 된다.

7) 삼항 연산자

'이것' 아니면 '저것'과 같이 단순하게 선택사항이 두 가지 뿐이라면
if, else 구문은 다소 코드가 길어지는 감이 있다.
이럴때 아주 짧게 쓸 수 있는 자바스크립트 문법이 바로 삼항 연산자 이다.
리엑트 네이티브로 앱을 만들 때 가장 많이 사용되는 조건문이다.

ex 1)

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 값 할당  

[해석]
10은 2보다 당연히 크기 때문에 '?(물음표)' 뒤의 값이 result에 담겨지게 된다.
만약 앞의 10 > 2 부분의 조건이 거짓이게 된다면, ' : ' 뒤에 있는 값이 result에 담기게 된다.

ex2)

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'
import data from './data.json';

export default function App() {
  let tip = data.tip;
  let todayWeather = 10 + 17;
  let todayCondition = "흐림"
  return (
    /* 생략 */
      <View style={styles.cardContainer}>
        { 
          tip.map((content,i)=>{
          
               /* HERE 💡 */             /* HERE 💡 */
            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>           /* HERE 💡 */
            </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>
  );
}

const styles = StyleSheet.create({
  //생략
  
  cardEven:{
    flex:1,
    flexDirection:"row",
    margin:10,
    
    // HERE 💡
    backgroundColor:"#FFFED7",
    
    borderRadius:20,
    borderBottomWidth:0.5,
    borderBottomColor:"#eee",
    paddingBottom:10
  },
  cardOdd:{
    flex:1,
    flexDirection:"row",
    margin:10,
    borderBottomWidth:0.5,
    
    // HERE 💡
    borderBottomColor:"#eee",
    
    paddingBottom:10
  },

});

[해석]
‘i % 2 == 0 ?’ 이라는 조건이 있는데 저기서 ‘%(퍼센트 연산자)’
앞에 있는 수와 뒤에 있는 수의 나눗셈의 결과의 나머지 를 뜻하며
‘i’ 는 순서를 나타내는데 첫 번째는 0, 두 번째는 1, 이렇게 4까지 존재한다.
2 로 나누었을 때 나머지는 0 이다 라는 것은 짝수 다 라는 것을 의미하는데,
‘cardEven’ 이라는 옷을 입히고 짝수일 때
#FFFED7 이라는 노란색 배경색을 입혔고

반대로 홀수일 때, ‘cardOdd’ 라는 옷을 입히고 #eee 라는 기존의 흰색 배경을 입힌 것을 볼 수 있다.

긴 글 읽어주셔서 감사합니다 🙏

좋은 웹페이지 즐겨찾기