Expo 설치와 실행까지 완료되었으니 이제 본격적으로 간단한 앱 화면을 꾸며보도록 하겠습니다!
expo가 생성해준 기본 앱의 파일들을 살펴보면 App.js라는 파일이 있는데 App.js는 JSX문법으로 그려져 준비된 화면을 반환합니다. JSX는 자바스크립트를 확장한 문법으로 태그를 통해 자바스크립트의 모든 기능을 쉽게 사용할 수 있습니다.
JSX의 기본 문법을 몇가지 소개해드리겠습니다.
App.js파일의 View나 Text 같은 문법은 임의로 만든 태그들이 아닙니다. 리액트 네이티브에서 제공해주는, 이미 존재하는 태그 문법을 가져와서 사용하는 겁니다. App.js 파일 상단을 보면 우리가 화면을 그릴 때 사용할 태그들을 가져와 준비해 놓습니다.
import { StatusBar } from 'expo-status-bar';
import React from 'react';
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="auto" />
</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>
);
}
이 부분을 보면 어떤 태그는 닫고 어떤 태그는 스스로 닫힙니다.
리액트 네이티브 공식문서와 Expo 공식문서를 보면 사용 법이 잘 나와있으니 링크를 참고해 주세요!
여기서 엘리먼트는 <View>영역</View>
과 같이 닫는 태그로 온전히 화면의 한 영역을 구성할 때 JSX에선 엘리먼트라 부릅니다.
//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>
);
}
//View 엘리먼트 밖에 StatusBar가 나와 있으므로 엘리먼트 전체를 감싸는 엘리먼트가
//없어서 오류가 납니다.
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
</View>
<StatusBar style="auto" />
);
}
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',
},
});
먼저 결과를 미리 보여드리겠습니다.
import React from 'react'
import {View, Text, StyleSheet, Image, TouchableOpacity} from 'react-native'
export default function AboutPage() {
const aboutImage = "https://firebasestorage.googleapis.com/v0/b/sparta-image.appspot.com/o/lecture%2FaboutImage.png?alt=media&token=13e1c4f6-b802-4975-9773-e305fc7475c4"
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.desc01}>많은 내용을 간결하게 담아내려 노력했습니다!</Text>
<Text style={styles.desc02}>꼭 완주 하셔서 꼭 여러분것으로 만들어가시길 바랍니다.</Text>
<TouchableOpacity style={styles.button}>
<Text style={styles.buttonText}>여러분의 인스타계정</Text>
</TouchableOpacity>
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex:1,
backgroundColor:"#1F266A",
alignItems:"center"
},
title: {
fontSize:30,
fontWeight:"700",
color:"#fff",
paddingLeft:30,
paddingTop:100,
paddingRight:30
},
textContainer: {
width:300,
height:500,
backgroundColor:"#fff",
marginTop:50,
borderRadius:30,
justifyContent:"center",
alignItems:"center"
},
aboutImage: {
width:150,
height:150,
borderRadius:30
},
desc01: {
textAlign:"center",
fontSize:20,
fontWeight:"700",
paddingLeft:22,
paddingRight:22
},
desc02: {
textAlign:"center",
fontSize:15,
fontWeight:"700",
padding:22
},
button: {
backgroundColor:"orange",
padding:20,
borderRadius:15
},
buttonText: {
color:"#fff",
fontSize:15,
fontWeight:"700"
}
})
<View></View>
화면의 영역(레이아웃)을 잡아주는 엘리먼트입니다. 우리는 이 View 엘리먼트로 화면을 원하는 대로 분할 할 수도 있습니다.
<Text></Text>
앱에 글을 작성하려면 반드시 사용해야하는 엘리먼트입니다.
View 엘리먼트 안에서 문자를 작성하면 오류가 발생합니다!
<Image/>
이미지를 가져오는 방식은 두 가지 방식이 있습니다. assets 폴더(이미지를 담아두는 폴더)에 있는 이미지를 가져와서 사용하는 방법과 (import),
외부 이미지 링크를 넣어서 사용하는 방식입니다(uri).
상단에 jsimport 이미지명 from "이미지 위치"
로 이미지를 불러오고 <Image source={이미지명}/>
방식으로 사용합니다.
<Image source={{uri:"이미지주소"}}/>
방식으로 사용합니다.
<TouchableOpacity></TouchableOpacity>
임의의 영역과 디자인에 버튼 기능을 달고 싶을 때 주로 사용하는 태그입니다.
태그에 스타일을 주는 방식 또한 리액트 네이티브에서 제공하는 StyleSheet 기능을 가져와 적용합니다.
사용할 땐 모든 태그에 공통적으로 있는 style 속성에 아래서 만든 객체 키값을 부여하여 적용 합니다.
가장 바깥에 있는 View 태그를 보면
다음과 같이 styles 속성에 styles 객체 container 키를 연결한 것을 확인 할 수 있습니다.
<View style={styles.container}>
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"
}
});
앱 화면을 구성할 때 사실 flex가 가장 중요하다고 봐도 과언이 아닙니다. 영역의 레이아웃을 결정하기 때문입니다!
flex
flex는 상대적입니다. 위 코드에서는 flex:1 하나 밖에 사용하지 않아 전체 영역을 가져가지만 다른 곳에 flex:2를 추가한다면 flex:1은 전체의 1/3을 차지하고 flex:2는 2/3를 차지합니다.
즉, 같은 레벨의 엘리먼트들의 flex 합을 각자의 flex 속성값 대로 가져갑니다.
flexDirection
자리 잡은 영역의 방향입니다.
row는 가로 방향, column은 세로방향으로 영역을 배치합니다. 기본 값은 column입니다.
justifyContent
justifyContent는 flexDirection과 동일한 방향으로 정렬하는 속성입니다
flexDirection: 'column'에서 justifyContent는 상하 정렬,
flexDirection: 'row'에서 justifyContent는 좌우 정렬을 뜻합니다.
flex-start, center, flex-end, space-between, space-around 속성을 가집니다.
alignItems
Align Items는 Flex Direction과 수직한 방향(반대 방향이라고 생각하면 편합니다)으로 정렬하는 속성입니다.
flexDirection: 'column'에서 alignItems는 좌우 정렬,
flexDirection: 'row'에서 alignItems는 상하 정렬을 뜻합니다
flex-start, center, flex-end, stretch 속성을 가집니다.
위에 모든 것들을 다 외우고 있어야 될 필요는 없습니다! 그때그때 필요한 것들을 찾아보고 공식문서를 참고하면 됩니다.