앱개발 종합반 2주차

React Native

Javascript 언어 중의 하나로 Android App과 iOS App 모두를 만들어주는 library

Expo

React Native로 App 개발이 가능하다고 했지만 특정 상황에서는 쉽지 않는데, 이를 수월하게 도와주는 도구
Node.js, NPM, yarn

Expo 실행

  • 앱생성 : expo init sparta-myhoneytip
  • 앱폴더 이동 : cd sparta-myhoneytip
  • 앱실행 및 적용 : expo start
  • QR 코드 통해 Expo 앱을 통해 스마트폰에서 적용

JSX 문법

App.js

import React from 'react'; 
import { StyleSheet, Text, View } from 'react-native'; 
export default function App() { 
    console.disableYellowBox = true; 
    //return 구문 밖에서는 슬래시 두개 방식으로 주석 
     
    return ( 
    ); 
} 
const styles = StyleSheet.create({ 
});

return (); 안에 JSX 문법 코드를 넣어준다. 화면을 그려준다고 해서 rendering이라고 하기도 한다.

JSX

  • [Expo 공식사용 설명서](https://docs.expo.io/versions/v38.0.0/react-native/view/)
  • [React Native 공식 문서](https://reactnative.dev/docs/view)
import { StatusBar } from 'expo-status-bar'; 
import React from 'react'; 
import { StyleSheet, Text, View } from 'react-native'; 

export default function App() { 
  console.disableYellowBox = true; 
  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', 
  }, 
});

View

화면의 영역(레이아웃)을 잡아주는 엘리먼트

import React from 'react'; 
import { StyleSheet, Text, View } from 'react-native'; 
export default function App() { 
  return ( 
    <View style={styles.container}> 
      <View style={styles.subContainerOne}></View> 
      <View style={styles.subContainerTwo}></View> 
    </View> 
  ); 
} 
const styles = StyleSheet.create({ 
  container: { 
    flex: 1, 
    backgroundColor: '#fff', 
  }, 
  subContainerOne: { 
    flex:1, 
    backgroundColor:"yellow" 
  }, 
  subContainerTwo: { 
    flex:1, 
    backgroundColor:"green" 
  } 
});

이 코드에서 핵심만 보면, 다음과 같다.

export default function App() { 
  return ( 
    <View style={styles.container}> 
      <View style={styles.subContainerOne}></View> 
      <View style={styles.subContainerTwo}></View> 
    </View> 
  ); 
}

Text

레이아웃 안에서 앱에 글을 작성하기 위해 반드시 사용해야 하는 엘리먼트.

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

export default function App() { 
  return ( 
    <View style={styles.container}> 
      <Text>문자는 Text 태그 사이에 작성!!</Text> 
      <Text>문자는 Text 태그 사이에 작성!!</Text> 
      <Text>문자는 Text 태그 사이에 작성!!</Text> 
      <Text>문자는 Text 태그 사이에 작성!!</Text> 
      <Text>문자는 Text 태그 사이에 작성!!</Text> 
      <Text>문자는 Text 태그 사이에 작성!!</Text> 
      <Text>문자는 Text 태그 사이에 작성!!</Text> 
      <Text>문자는 Text 태그 사이에 작성!!</Text> 
      <Text>문자는 Text 태그 사이에 작성!!</Text> 
      <Text>문자는 Text 태그 사이에 작성!!</Text> 
      <Text>문자는 Text 태그 사이에 작성!!</Text> 
    </View> 
  ); 
} 

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

ScrollView

앱 화면을 벗어나는 영역의 경우 ScrollView 엘리먼트로 감싸면 스크롤이 가능해지면서 모든 컨텐츠를 볼 수 있다.

import React from 'react'; 
import { StyleSheet, Text, View, ScrollView } from 'react-native'; 
export default function App() { 
  return ( 
    <ScrollView style={styles.container}> 
      <View style={styles.textContainer}> 
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text> 
      </View> 
      <View style={styles.textContainer}> 
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text> 
      </View> 
      <View style={styles.textContainer}> 
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text> 
      </View> 
      <View style={styles.textContainer}> 
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text> 
      </View> 
      <View style={styles.textContainer}> 
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text> 
      </View> 
      <View style={styles.textContainer}> 
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text> 
      </View> 
      <View style={styles.textContainer}> 
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text> 
      </View> 
    </ScrollView> 
  ); 
} 
const styles = StyleSheet.create({ 
  container: { 
    flex: 1, 
    backgroundColor: '#fff', 
  }, 
  textContainer: { 
    height: 100, 
    borderColor: '#000', 
    borderWidth: 1, 
    borderRadius: 10, 
    margin: 10, 
  }, 
  textStyle: { 
    textAlign: "center" 
  } 
});

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> 
        {/* 버튼 onPress 속성에 일반 함수를 연결 할 수 있습니다. */} 
        <Button  
          style={styles.buttonStyle}  
          title="버튼입니다 " 
          color="#f194ff"  
          onPress={function(){ 
            Alert.alert('팝업 알람입니다!!') 
          }} 
        /> 
        {/* ES6 문법으로 배웠던 화살표 함수로 연결 할 수도 있습니다. */} 
        <Button  
            style={styles.buttonStyle}  
            title="버튼입니다 " 
            color="#FF0000"  
            onPress={()=>{ 
              Alert.alert('팝업 알람입니다!!') 
            }} 
          /> 
          </View> 
    </View> 
  ); 
} 
const styles = StyleSheet.create({ 
  container: { 
    flex: 1, 
    backgroundColor: '#fff', 
  }, 
  textContainer: { 
    height:100, 
    margin:10, 
  }, 
  textStyle: { 
    textAlign:"center" 
  }, 
});

위 예제에서 찾아보듯 공식문서(바로가기)에 보면 다음 태그 형식으로 되어 있다.

<Button 
  onPress={onPressLearnMore} 
  title="Learn More" 
  color="#841584" 
  accessibilityLabel="Learn more about this purple button" 
/>

onPress

  • onPress = {function(PressEvent)} : 함수를 넣을 수도 있으며, 함수 구현부를 JSX 밖에서 구현한 다음 연결할 수도 있다.
  • 버튼을 눌렀을 때 이벤트 작동
  • ex) onPress = {() => Alert.alert('Simple Button pressed')}
    title
  • 버튼 내에 글자가 보이도록 함.
    color
  • iOs에서는 글자의 색깔이며, Android에서는 버튼의 배경 색상이 됨.

(함수 구현부를 SX 밖에서 구현 후 연결한 코드)

export default function App() { 
  //화살표 함수 형식으로 함수를 정의하고 
  //jSX문법 안에서 사용할 수 있습니다 
  const customAlert = () => { 
    Alert.alert("JSX 밖에서 함수 구현 가능!") 
  } 
  return ( 
    <View style={styles.container}> 
      <View style={styles.textContainer}> 
        <Text style={styles.textStyle}>아래 버튼을 눌러주세요</Text> 
        {/* onPress에 밖에서 구현한 함수 이름을 고대로 넣을 수도 있고*/} 
        <Button  
          style={styles.buttonStyle}  
          title="버튼입니다 " 
          color="#f194ff"  
          onPress={customAlert} 
        /> 
        {/* onPress를 누르면 속성에 바로 구현해 놓은 함수 안에 customALert함수를 두고 실행할 수 있게도 가능합니다 */} 
        <Button  
            style={styles.buttonStyle}  
            title="버튼입니다 " 
            color="#FF0000"  
            onPress={() => {customAlert()}} 
          /> 
          </View> 
    </View> 
  ); 
}

TouchableOpacity

Button 엘리먼트는 본인의 영역을 갖지만 스타일에도 신경을 써야 하고 ScrollView에서처럼 카드 형식으로 만들면 버튼 태그를 사용하기 어렵다.
그런 경우 영역을 버튼처럼 사용할 수 있다. 해당 영역을 눌렀을 때 이벤트가 발생하게 할 수 있다.

import React from 'react'; 
import { StyleSheet, Text, View, ScrollView, TouchableOpacity, Alert } from 'react-native'; 
export default function App() { 
  const customAlert = () => { 
    Alert.alert("TouchableOpacity에도 onPress 속성이 있습니다") 
  } 
  return ( 
    <ScrollView style={styles.container}> 
      <TouchableOpacity style={styles.textContainer} onPress={customAlert}> 
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text> 
      </TouchableOpacity> 
      <TouchableOpacity style={styles.textContainer} onPress={customAlert}> 
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text> 
      </TouchableOpacity> 
      <TouchableOpacity style={styles.textContainer} onPress={customAlert}> 
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text> 
      </TouchableOpacity> 
      <TouchableOpacity style={styles.textContainer} onPress={customAlert}> 
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text> 
      </TouchableOpacity> 
      <TouchableOpacity style={styles.textContainer} onPress={customAlert}> 
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text> 
      </TouchableOpacity> 
      <TouchableOpacity style={styles.textContainer} onPress={customAlert}> 
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text> 
      </TouchableOpacity> 
      <TouchableOpacity style={styles.textContainer} onPress={customAlert}> 
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text> 
      </TouchableOpacity> 
    </ScrollView> 
  ); 
} 
const styles = StyleSheet.create({ 
  container: { 
    flex: 1, 
    backgroundColor: '#fff', 
  }, 
  textContainer: { 
    height:100, 
    borderColor:'#000', 
    borderWidth:1, 
    borderRadius:10, 
    margin:10, 
  }, 
  textStyle: { 
    textAlign:"center" 
  } 
});

Image

앱에 이미지를 넣는 방법은 두 가지가 있다.

  • assets 폴더에 있는 이미지를 가져와서 사용하는 방법(import)
  • 외부 이미지 링크를 넣어서 사용하는 방법

assets 폴더에 있는 이미지 가져와 사용하기

import React from 'react'; 
import { StyleSheet, Text, View, Image } from 'react-native'; 
//이렇게 상단에 가져와 사용할 이미지를 불러옵니다 
import favicon from "./assets/favicon.png" 
export default function App() { 
  return ( 
    <View style={styles.container}> 
      {/*이미지 태그 soruce 부분에 가져온 이미지 이름을 넣습니다 */} 
      <Image  
        source={favicon} 
	// 사용설명서에 나와 있는 resizeMode 속성 값을 그대로 넣어 적용합니다 
        resizeMode={"repeat"} 
        style={styles.imageStyle} 
      /> 
    </View> 
  ); 
} 
const styles = StyleSheet.create({ 
  container: { 
    flex: 1, 
    backgroundColor: '#fff', 
    //혹시 미리 궁금하신 분들을 위해 언급하자면, 
    //justifyContent와 alignContent는 영역 안에 있는 콘텐츠들을 정렬합니다 
    justifyContent:"center", 
    alignContent:"center" 
  }, 
  imageStyle: { 
    width:"100%", 
    height:"100%", 
    alignItems:"center", 
    justifyContent:"center" 
  } 
});

image 부분만 집중하면,

<Image  
 source={favicon} 
 // 사용설명서에 나와 있는 resizeMode 속성 값을 그대로 넣어 적용합니다 
 resizeMode={"repeat"} 
 style={styles.imageStyle} 
/>

외부 이미지 사용하기

source 부분에 uri를 사용하면 도며, resizemode에 cover 라는 값을 넣어본다.

import React from 'react'; 
import { StyleSheet, Text, View, Image } from 'react-native'; 
//이렇게 상단에 가져와 사용할 이미지를 불러옵니다 
import favicon from "./assets/favicon.png" 
export default function App() { 
  return ( 
    <View style={styles.container}> 
      {/*이미지 태그 soruce 부분에 가져온 이미지 이름을 넣습니다 */} 
      <Image  
        source={{uri:'https://images.unsplash.com/photo-1424819827928-55f0c8497861?fit=crop&w=600&h=600%27'}} 
	// 사용설명서에 나와 있는 resizeMode 속성 값을 그대로 넣어 적용합니다 
        resizeMode={"cover"} 
        style={styles.imageStyle} 
      /> 
    </View> 
  ); 
} 
const styles = StyleSheet.create({ 
  container: { 
    flex: 1, 
    backgroundColor: '#fff', 
    //혹시 미리 궁금하신 분들을 위해 언급하자면, 
    //justifyContent와 alignContent는 영역 안에 있는 콘텐츠들을 정렬합니다 
    justifyContent:"center", 
    alignContent:"center" 
  }, 
  imageStyle: { 
    width:"100%", 
    height:"100%", 
    alignItems:"center", 
    justifyContent:"center" 
  } 
});

image 부분만 집중하면,

{/*이미지 태그 soruce 부분에 가져온 이미지 이름을 넣습니다 */}  
<Image  
 source={{uri:'https://images.unsplash.com/photo-1424819827928-55f0c8497861?fit=crop&w=600&h=600%27'}} 
 // 사용설명서에 나와 있는 resizeMode 속성 값을 그대로 넣어 적용합니다 
 resizeMode={"cover"} 
 style={styles.imageStyle} 
/>

모든 태그에 공통적으로 있는 styles 속성
이 속성을 사용하기 위해 이미 'react-native'에서 import 해 왔음.

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

태그에 스타일을 주는 방식 또난 리액트 네이티브에서 제공하는 StyleSheet 기능을 가져와 적용하 것으로, 결국 객체(딕셔너리)를 하나 만들어 사용한 것이다.

View 태그에서 style 속성에 styles 객체 container 키를 연결한 것을 확인할 수 있다.

<View style={styles.container}>
...
</View>
const styles = StyleSheet.create({ 
  container: { 
    flex: 1, 
    backgroundColor: '#fff', 
    justifyContent: "center", 
    alignContent: "center" 
  },

화면을 꾸며주는 StyleSheet 문법
자주 사용하는 스타일 속성

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" 
  } 
});

margin, padding
margin과 padding은 영역의 바깥과 안의 여백을 결정

속성은 다 외우지 못하므로, 검색해서 사용하자.
"react  native 필요한 스타일" 등으로 검색

flex

앱 화면을 구성할 때 영역의 레이아웃을 결정함.
flex는 상대적 크기로 영역을 나눔.

(예제 1)

import React from 'react'; 
import { StyleSheet, Text, View } from 'react-native'; 
export default function App() { 
  return ( 
    <View style={styles.container}> 
      <View style={styles.containerOne}> 
      </View> 
      <View style={styles.containerTwo}> 
      </View> 
    </View> 
  ); 
} 
const styles = StyleSheet.create({ 
  container: { 
    flex:1 
  }, 
  containerOne: { 
    flex:1, 
    backgroundColor:"red" 
  }, 
  containerTwo:{ 
    flex:2, 
    backgroundColor:"yellow" 
  } 
});

위 코드를 보면,  View 태그로 container가 가장 상위에 있고, 그 안에 containerOne과 containerTwo가 동일한 레벨로 나누어져 있다.

styles에 보면, 부모 요소인 container에는 flex: 1로 되어 있어 영역 전체를 차지한다. 그 아래 containerOne은 flex 1, containerTwo는 fex 2로 되어 있다. containerOne과 containerTwo는 같은 레벨이므로 1 + 2 = 3 이므로, containerOne의 영역은 1/3, containerTwo의 영역은 2/3가 된다.

정리하면,
container = 1
containerOne = 1/3
containerTwo = 2/3

(예제2)

import React from 'react'; 
import { StyleSheet, Text, View } from 'react-native'; 
export default function App() { 
  return ( 
    <View style={styles.container}> 
      <View style={styles.containerOne}> 
      </View> 
      <View style={styles.containerTwo}> 
        <View style={styles.innerOne}> 
        </View> 
        <View style={styles.innerTwo}> 
        </View> 
      </View> 
    </View> 
  ); 
} 
const styles = StyleSheet.create({ 
  container: { 
    flex:1 
  }, 
  containerOne: { 
    flex:1, 
    backgroundColor:"red" 
  }, 
  containerTwo:{ 
    flex:2, 
    backgroundColor:"yellow" 
  }, 
  innerOne: { 
    flex:1, 
    backgroundColor:"blue" 
  }, 
  innerTwo: { 
    flex:4, 
    backgroundColor:"orange" 
  } 
});

container 아래 containerOne, containerTwo가 있고, containerTwo 안에 innerOne, innerTwo가 있다.

flex 속성은 container는 1, containerOne 1, containerTwo 2, innerOne 1, innerTwo 4
containerOne과 containerTwo는 같은 레벨이므로 1 + 2 = 3
innerOne과 innerTwo는 같은 레벨이므로 1 + 4 = 5

container = 1
containerOne = 1/3
containerTwo = 2/3
innerOne = 2/15 (2/3 x 1/5)
innerTwo = 8/15 (2/3 x 4/5)

flexDirection

영역의 방향을 결정
row : 가로 방향으로 영역을 배치
colum : 세로 방향으로 영역을 배치, 기본값

(예제3)

import React from 'react'; 
import { StyleSheet, Text, View } from 'react-native'; 
export default function App() { 
  return ( 
    <View style={styles.container}> 
      <View style={styles.containerOne}> 
      </View> 
      <View style={styles.containerTwo}> 
        <View style={styles.innerOne}> 
        </View> 
        <View style={styles.innerTwo}> 
        </View> 
      </View> 
    </View> 
  ); 
} 
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" 
  } 
});

justifyContent

justifyContent는 flexDirection과 동일한 방향으로 컨텐츠를 정렬하는 속성

  • flexDirection: 'colum'  ==> justifyContent는 상하 정렬
  • flexDirection: 'row' ==> justifyContent는 좌우 정렬

justifyContent의 속성

  • flex-start
  • center
  • flex-end
  • space-between
  • space-around

(예제4)

import React from 'react'; 
import { StyleSheet, Text, View } from 'react-native'; 
export default function App() { 
  return ( 
    <View style={styles.container}> 
      <View style={styles.containerOne}> 
      </View> 
      <View style={styles.containerTwo}> 
        <View style={styles.innerOne}> 
          
        </View> 
        <View style={styles.innerTwo}> 
          <Text>!!컨텐츠!!</Text> 
        </View> 
      </View> 
    </View> 
  ); 
} 
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-start", 
    backgroundColor:"orange" 
  } 
});

alignItems

alignItems는 flexDirection과 수직 방향(반대방향)으로 정렬하는 속성

  • flexDirection: 'colum' ==> alignItems는 좌우 정렬
  • flexDirection: 'row' ==> alignItems는 상하 정렬

속성은, flex-start, center, flex-end, stretch

(예제5)

import React from 'react'; 
import { StyleSheet, Text, View } from 'react-native'; 
export default function App() { 
  return ( 
    <View style={styles.container}> 
      <View style={styles.containerOne}> 
      </View> 
      <View style={styles.containerTwo}> 
        <View style={styles.innerOne}> 
          
        </View> 
        <View style={styles.innerTwo}> 
          <View style={styles.content}></View> 
        </View> 
      </View> 
    </View> 
  ); 
} 
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" 
  } 
});

앱 메인화면 만들기

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 ( 
    /* 
      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", 
  } 
}); 

모듈, 반복문 사용

data.json 사용 시

import React from 'react'; 
import main from './assets/main.png'; 
import { StyleSheet, Text, View, Image, TouchableOpacity, ScrollView } from 'react-native'; 
import data from './data.json'; 
export default function App() { 
  console.disableYellowBox = true; 
  //return 구문 밖에서는 슬래시 두개 방식으로 주석 
  let tip = data.tip; 
  let todayWeather = 10 + 17; 
  let todayCondition = "흐림" 
  return ( 
    /* 
      return 구문 안에서는 {슬래시 + * 방식으로 주석 
    */ 
    <ScrollView style={styles.container}> 
      <Text style={styles.title}>나만의 꿀팁</Text> 
      <Text style={styles.weather}>오늘의 날씨: {todayWeather + '°C ' + todayCondition} </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 */} 
        { 
          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> 
  ); 
} 
const styles = StyleSheet.create({ 
  container: { 
    //앱의 배경 색 
    backgroundColor: '#fff', 
  }, 
  title: { 
    //폰트 사이즈 
    fontSize: 20, 
    //폰트 두께 
    fontWeight: '700', 
    //위 공간으로 부터 이격 
    marginTop: 50, 
    //왼쪽 공간으로 부터 이격 
    marginLeft: 20 
  }, 
  weather: { 
    alignSelf: "flex-end", 
    paddingRight: 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 
  }, 
  middleButtonText: { 
    color: "#fff", 
    fontWeight: "700", 
    //텍스트의 현재 위치에서의 정렬  
    textAlign: "center" 
  }, 
  middleButton04: { 
    width: 100, 
    height: 50, 
    padding: 15, 
    backgroundColor: "#f886a8", 
    borderRadius: 15, 
    margin: 7 
  }, 
  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", 
  }, 
});

JSX 안에서도 자바스크립트 문법을 사용할 수 있다.
{ } 안에 표현식을 사용하는 것!

App.js로 다른 js 파일 불러오기

App.js에서 코드를 변경해가며 만들 수도 있지만, 다른 .js 파일을 만들어 App.js를 통해 불러올 수도 있다.

예컨데, pages 라는 폴더를 만들고, 그 아래에 MainPage.js, AboutPage.js를 만들었다고 하자. 이 두 개의 파일에 불어올 코드를 작성했다고 하면, App.js를 다음과 같이 수정하여 MainPage.js 혹은 AboutPage.js를 불러올 수 있다.

여기서 중요한 것은 MainPage.js와 AboutPage.js에서 함수의 이름도 바뀌어야 한다는 것이다.

export default function MainPage() { }

export default function AboutPAge() { }

App.js : MainPage.js 불러오기

import React from 'react'; 
import MainPage from './pages/MianPage'; 
export default function App() { 
  return (<MainPage/>); 
}

App.js : AboutPage.js 불러오기

import React from 'react'; 
import AboutPage from './pages/AboutPage'; 
export default function App() { 
  return (<AboutPage/>);
}

지금까지 만들어왔던 App.js 코드를 MainPage.js로 옮기고 import 할 주소 등만 수정해주면 App.js를 통해 불러올 수 있다.

이제 AboutPage.js에서 만들고자 하는 앱화면을 코딩한 뒤 App.js로 불러온다.

작성을 위한 기본 구조이다.

import React from 'react'; 
import { StyleSheet, Text, View } from 'react-native'; 
export default function App() { 
    console.disableYellowBox = true; 
    //return 구문 밖에서는 슬래시 두개 방식으로 주석 
     
    return ( 
    ); 
} 
const styles = StyleSheet.create({ 
});

내가 완성한 AboutPage.js 코드

import React from 'react'; 
import { StyleSheet, Text, View, Image, TouchableOpacity } from 'react-native'; 
import main from '../assets/mainimage.png'; 
export default function AboutPage() { 
    console.disableYellowBox = true; 
    //return 구문 밖에서는 슬래시 두개 방식으로 주석 
    return ( 
        <View style={styles.container}> 
            <View style={styles.subContainerOne}> 
                <Text style={styles.title}>HI! 스파르타코딩 앱개발 반에 오신 것을 환영합니다</Text> 
            </View> 
            <View style={styles.subContainerTwo}> 
                <View style={styles.boxOne}> 
                    <Image style={styles.mainImage} source={main} /> 
                </View> 
                <View style={styles.boxTwo}> 
                    <Text style={styles.contentsOne}>많은 내용을 간결하게 담아내려 노력했습니다!</Text> 
                    <Text style={styles.contentsTwo}>꼭 완주하셔서 꼭 여러분 것으로 만들어가시길 바랍니다.</Text> 
                </View> 
                <View style={styles.boxThree}> 
                    <TouchableOpacity style={styles.button}><Text style={styles.insta}>여러분의 인스타계정</Text></TouchableOpacity> 
                </View> 
            </View> 
            <View style={styles.subContainerThree}> 
            </View>            
        </View> 
    ); 
} 
const styles = StyleSheet.create({ 
    container: { 
        flex: 1, 
        backgroundColor: "#000066", 
    }, 
    subContainerOne: { 
        flex: 2, 
        margin: 30, 
    }, 
    title: { 
        color: "#fff", 
        marginTop: 60, 
        textAlign: "center", 
        fontSize: 35, 
    }, 
    subContainerTwo: { 
        flex: 7, 
        margin: 20, 
        borderWidth: 1, 
        borderColor: "#fff", 
        borderRadius: 20, 
        backgroundColor: "#fff" 
    }, 
    boxOne: { 
        flex: 2, 
    }, 
    mainImage: { 
        width: 200, 
        height: 200, 
        alignSelf: "center", 
        marginTop: 50, 
        borderRadius: 40, 
    }, 
    boxTwo: { 
        flex: 1, 
    }, 
    contentsOne:{ 
        textAlign: "center", 
        fontSize: 25, 
        fontWeight: "700" 
    }, 
    contentsTwo: { 
        marginTop: 10, 
        textAlign: "center", 
        fontSize: 18, 
        fontWeight: "700", 
    }, 
    boxThree: { 
        flex: 1, 
    }, 
    button: { 
        width: 180, 
        height: 50, 
        backgroundColor: "orange", 
        alignSelf: "center", 
        borderRadius: 10, 
    }, 
    insta: { 
        color: "#fff", 
        fontSize: 17, 
        textAlign: "center", 
        padding: 13, 
    }, 
    subContainerThree: { 
        flex: 1, 
    },  
});

좋은 웹페이지 즐겨찾기