sogno
카테고리
작성일
2023. 1. 23. 20:05
작성자
sognociel

스마트폰의 앱 종류는 네이티브 앱, 크로스 플랫폼, 하이브리드 앱 세 종류로 나누어진다.

 

  • 네이티브 앱
    Swift, Kotlin, Java 등으로 OS에 특화된 개발이며 뛰어난 성능, 많은 기능을 사용 가능하다. 다만 필요한 지식이 많아 개발 속도가 느리다는 것이 단점이라고 한다.
  • 크로스 플랫폼
    React Native, Flutter 등 하나의 언어로 여러 플랫폼의 개발이 가능하다. 빠른 개발이 가능하지만 네이티브 대비 낮은 성능 및 기능 제한이 있다.
  • 하이브리드 앱
    하나의 언어로 여러 플랫폼을 개발하며 장단점은 크로스 플랫폼과 같다.

 

 

React Native는?

android와 iOS 각각 만들기 보다는 JavaScript 하나로 만들어버리자고 나온 것이 React Native이다.

 

Expo는?

React Native조차 복잡하다고 나온 것

 

👉 Expo로 갈 수록 쉬워지기는 하지만, 기능적인 부분에서 제한이 있다. (업데이트 되는 기간도 필요함...)

 

 

 

React Native 개발 환경 설정

Expo CLI | Third-party service. 비용을 지불할 필요가 없음. 언제든지 React Native CLI로 전환할 수 있다. 패키지와 툴 사용이 편리함

cf.) third-party package | 프로그램과 개발자 사이. 플러그인, 라이브러리, 프레임워크

$ npm install -g expo-cli
$ npx create-expo-app 프로젝트명

 

React Native CLI | 추가적인 구성 및 설정은 직접 해야한다. 특정 기기 활용(카메라 등) Expo보다 작업이 번거롭다.

 

만들어진 프로젝트

assets | 이미지 파일들을 넣어놓는 폴더
node_modules | 내부적으로 사용되는 third party package
package.json | 프로젝트의 의존성(Dependencies)
app.json | React Native 앱의 설정과 실행 방식을 구성하는 파일

 

 

 

Expo Go

핸드폰을 통해 현재 개발하고 있는 프로젝트를 실제 앱으로 돌려볼 수 있다.

npm start로 프로젝트를 실행하면 QR코드가 나오는데, 이 QR코드를 통해 핸드폰에서 애플리케이션처럼 실행이 가능해진다.

r을 눌러서 새로고침 할 수 있음!

 

cf.) 만약 아이폰 유저인데 안드로이드로 실행된 모습을 보고 싶다면?
로컬 머신에 실행되는 시뮬레이터를 설치하면 된다. (에뮬레이터)
안드로이드 | Android Studio
아이폰 | Xcode의 경우 Window나 Linux에서 실행할 수가 없다...

 

 

Android Studio

안드로이드 앱 화면을 볼 수 있는 시뮬레이터이다.

Android Studio를 실행하고, Virtual Device Manager를 클릭한다.
Play Store가 활성화 되어있는 기기를 선택 후 실행

이후 API 파일을 설치하고 (recommend로 나온다) Finish를 누르면

이렇게 내가 만든 버추얼 기기가 보인다. 재생 버튼을 클릭해서 실행하면 끝!

 

 

샘플 코드

import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View } from "react-native";

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Hello World!</Text>
      <StatusBar style="auto" />
    </View>
  );
}

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

Expo Go로 실행한 화면...!

Text와 View는 React Native(이하 RN)의 가장 중요한 내장 컴포넌트로 JSX 코드에 사용된다.

네이티브 기기는 브라우저가 아니라서 DOM을 가지고 있지 않으니 HTML 요소를 지원하지 않는다.

따라서 div, h2 같은 DOM을 통해 브라우저에서 작업할 때 사용할 수 있는 HTML 요소들을 사용할 수 없는 것.

 

Web Browser (react-dom) Native Component (Android) Native Component (iOS) React Native JSX
<div> android.View UIView <View>
<input> EditText UITextField <TextInput>
... ... ... ...

컴포넌트에 대해서는 공식문서 참고! 공식문서

 

 

 

StyleSheet

RN에는...CSS가... 없다..>!!!!!!
인라인 스타일을 적용하거나, StyleSheet 객체를 사용..!

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
  dummyText: {
    margin: 16,
    padding: 16,
    borderWidth: 2,
    borderColor: "green",
  },
});

스타일을 정의해놓고 컴포넌트 안에서 아래와 같이 사용하면 된다.

<Text style={styles.dummyText}>Hello World!</Text>

 

StyleSheet는 자동완성 기능 + 내부 값에 대해 자동으로 오류 판별을 해주는 기능을 가지고 있다. (유효성 검증)

예를 들어 margin: "16px" 로 했을 때, "16px"이라는 값은 적용되지 않으니 다르게 설정해라... 는 식으로 알려준다.

 

👉 flex-box

View 컴포넌트는 특정 스타일을 지정하지 않아도 기본적으로 flex를 사용하기 때문에, 스타일을 지정할 때 display:"flex"를 명시해 주지 않아도 된다. flexDirection은 "cloumn"이 기본값.

속성을 입력하고 Ctrl + Space바를 누르면 입력 가능한 값들을 확인할 수 있다.

레이아웃을 설정하는 데 있어서 flex:1과 같이 값을 설정해주며 비율을 맞춰주는 게 좋다. flex 값을 설정하지 않으면 요소들은 나타나기 위한 최소한의 공간만 차지하기 때문이다.

 

 

👉 Button의 style

React Native에서 버튼에는 style이 적용되지 않는데, 이를 알아볼 수 있는 방법이 있다.

style 프로퍼티가 적용 가능함
이건... 적용 안되는 것...

 

 

👉 Text 요소에 적용되지 않는 borderRadius

iOS에서는 Text 요소에 적용되지 않는 프로퍼티가 있는데, (borderRadius 등) 이를 해결할 수 있는 방법은 View로 Text를 감싸는 방식을 사용할 수 있다(Rapper 사용). 다만, 이렇게 한다면 텍스트 요소에는 또 다른 스타일 객체를 지정해 주어야 한다.
간단하게 말하자면..? 리스트를 출력하는 박스 따로, 텍스트 따로 만들어야 한다는 것이다.

{courseGoals.map((goal) => (
  <View key={v4()} style={styles.goalItem}>
    <Text style={styles.goalText}>{goal}</Text>
  </View>
))}

style 객체 중 goalItem과 goalText 부분

goalItem: {
  margin: 8,
  padding: 8,
  borderRadius: 6,
  backgroundColor: "#5e0acc",
},
goalText: {
  color: "white",
},

 

 

 

Event

RN은 ReactDOM 대신 다른 것을 사용하지만, 이벤트 처리, 상태 관리, React Hooks 등 React의 핵심 기능(웹용)은 그대로 사용할 수 있다.

 

todo리스트를 만들 때, input 창의 입력 값이 잘 받아와지는지 console.log로 테스트를 해 보았었는데, RN에서 console.log를 확인하는 방식은 VSCode의 콘솔창을 확인하면 된다.

Expo Go에서 입력창을 수정했을 때 그 값을 확인할 수 있다.

 

이벤트를 적용하는 방법은 React에서 적용한 방법처럼 onChage 등의 프로퍼티를 이용하면 되는데, 다만 주의할 점은 프로퍼티의 이름이 조금씩 다르다는 것이다

onChange의 경우 onChangeText, onClick의 경우 onPress로 적용이 되니 공식 문서를 잘 참고하면서 개발하자!

 

 

 

ScrollView

웹사이트에서는 사용 가능 공간을 넘어가면 자동적으로 스크롤이 생기는데, RN에서는 스크롤을 사용하려면 RN에서 제공하는 전용 컴포넌트로 명시적으로 지시해야 한다. 이 때 사용하는 컴포넌트가 ScrollView이다.
다만 ScrollView는 스크롤 가능한 '속성'만 제공해 줄 뿐, 스크롤 가능한 '영역'은 부모 요소가 결정하기 때문에 새롭게 View로 감싸서 높이를 지정해 주어야 한다.

외부 View는 화면상 해당 영역이 차지하는 공간을 제어하고, 내부 ScrollView는 해당 공간에 있는 항목을 전체 공간 내에서 스크롤 할 수 있도록 도와주는 것이다.

👉 ScrollView에 flex:5와 같이 영역 지정은 하지 않는 것!

 

다만 ScrollView는 길이가 한정적인 콘텐츠에 스크롤을 추가할 때 유용하다. (뉴스 기사가 조금 길다거나, 사용자가 어떤 장치를 이용하는지 몰라서 기사를 스크롤 하게 만들기 위해)

그래서 todo list와 같이 한정되지 않은 목록에는 ScrollView가 적합하지 않은데, 그 이유는 수백, 수천 개의 항목이 있을 때 현재 화면에서 보이지 않는 항목이라 할지라도 전체 항목을 렌더링 하기 때문이다. 항목이 몇 개든 상관없이 모든 자식 항목들을 렌더링하고 있기 때문에 성능에 문제가 생길 수 있다는 것.

👉 끝이 정해진, 분량이 제한된 콘텐츠에는 ScrollView가 적합! 그렇지 않은 콘텐츠는? -> FlatList 사용!

 

 

 

FlatList

FlatList는 보이는 화면만 렌더링하고 화면 밖의 항목은 사용자가 스크롤을 해야 로딩 및 렌더링을 하게 하는 RN의 전용 컴포넌트이다. 작은 임곗값을 가지는데(...? ...???) 사용자가 목록을 스크롤 하면서 항목에 가까워질 때만 해당 항목을 렌더링 한다. 목록이 1천 개가 있어도 대부분의 항목은 렌더링 하지 않음!!

사용방법은 ScrollView를 FlatList 컴포넌트로 바꿔주면 되는데, ScrollView에는 배열 데이터를 map을 이용하여 항목을 표시했다면 FlatList는 방법이 조금 다르다. (map을 쓰지 않음)

// ScrollView를 사용할 때
<View style={styles.goalsContainer}>
  <ScrollView>
    {courseGoals.map((goal) => (
      <View key={v4()} style={styles.goalItem}>
        <Text style={styles.goalText}>{goal.text}</Text>
      </View>
    ))}
  </ScrollView>
</View>

// FlatList를 사용할 때
<View style={styles.goalsContainer}>
  <FlatList
    data={courseGoals}
    renderItem={(itemData) => {
      return (
        <View style={styles.goalItem}>
          <Text style={styles.goalText}>{itemData.item.text}</Text>
        </View>
      );
    }}
  />
</View>

FlatList에서는 data프로퍼티에 배열로 이루어진 데이터를 주고, renderItem에서 화살표 함수를 사용하여 JSX를 return한다.

map을 사용할 때와 다른 점은 map에서는 item을 그대로 사용해도 되었지만, FlatList의 item에서는 item이라는 속성을 붙여주어야 한다는 것이다.

ex.) map에서 item을 사용 | item 또는 item.text (객체로 이루어진 데이터에서 text키의 값을 가져올 때)

FlatList에서 item을 사용 | item.item 또는 item.item.text

FlatList에서 나오는 item

 

key를 추가하는 두 가지 방법

map을 사용하여 항목을 출력하는 방식에서 반드시 모든 자식요소에 key 값이 들어가야 한다. 이는 React(웹)에서도 필수적인 요소! 다만, FlatList를 사용할 때는 어떻게 key를 추가하느냐? 2가지 방법이 있다.

 

1. FlatList에 전해주는 데이터를 객체형식으로 만들어 개별 항목에 key 값을 추가해 준다.

FlatList는 객체 목록일 때 더 잘 작동한다고 하는데, 예를 들면 {text: inputTest, key: v4()} 식으로 모든 항목에 key 값을 지정해 주는 것이다.

이렇게 데이터를 지정해 놓으면 FlatList에서 아이템들을 렌더링 하면서 자동적으로 key 값을 가져와 오류가 뜨지 않게 된다. 다만 key가 아니라 id 값을 사용하고자 한다면... ->2번으로

 

2. keyExtractor 사용

FlatList의 속성중에는 keyExtractor라는 것이 있는데, 이를 이용하여 key값을 지정해 주는 것이다. keyExtractor는 기본 키 속성 대신 반응 키에 대한 ID를 사용하도록 지시하는 속성이다.

// FlatList를 사용할 때
<View style={styles.goalsContainer}>
  <FlatList
    data={courseGoals}
    renderItem={(itemData) => {
      return (
        <View style={styles.goalItem}>
          <Text style={styles.goalText}>{itemData.item.text}</Text>
        </View>
      );
     keyExtractor={(item)=>item.id} // 만약 key가 아니라 id를 값으로 지정했을 때
    }}
  />
</View>

👉 동적 데이터를 가진 콘텐츠는? -> FlatList 사용!

 

 

 

-