본문 바로가기
Coding

[스파르타코딩클럽] APP 개발 종합반 - 3주차 개발일지

by 준아이덴티티 2022. 11. 23.
SMALL

 

 

 

 

 

  APP개발 종합반 3주차 수강이 완료됐다. 커피도 준비 완료됐으니 오늘은 3주차 개발일지를 써보련다. 먼저 앱개발에 뛰어든지 얼마 안 되어 지식이 부족한 점과 글 주변이 많이 좋지 않은 점 이해의 말씀 당부드린다.

 

 

 


 

 

⛵ 수업 목표

  1. 앱 개발을 위한 필수 리액트 기초 공부
  2. 앱 다운 앱을 위한 기능 적용
  3. 앱 상의 페이지 구성

 

 


 

 

리액트 네이티브 앱을 만들기 위해 알아야하는 최소한의 리액트 개념

 

 

  • 컴포넌트(Component)
  • 상태(State,useState)
  • 속성(Props)
  • useEffect

 

 

  이 개념들을 통해 앱 코드를 체계적으로 관리 및 화면 안에서 데이터를 자유자재로 관리함. 최소한의 리액트 개념을 배우는 이유는 리액트 네이티브(React Native)가 리액트(React.js) 기반으로 만들어진 앱 개발 기술이기 때문.

 

 

 

 

 

 

  리액트 네이티브는 리액트(React.js) 라이브러리 기반으로 만들어진 프레임워크다. 기본적인 구조가 리액트를 닮아있는 부분도 그 때문. 위에서 언급한 것처럼 다음과 같이 네 가지를 들 수 있다.

 

 

 

 

 

 


 

 

컴포넌트(Component)

 

 

  컴포넌트는 UI의 요소, 요소를 재사용 가능한 부분으로 조각내 운영하는 기법. 리액트 기반으로 만들어진 페이스북 웹사이트는 운영되는 컴포넌트가 수 만가지라고.

  컴포넌트는 화면의 모든 부분이다. 그리고 App.js의 큰 App 함수처럼, 코드 전체를 감싸고 있는 함수를 뜻하기도 한다.  따라서 App.js를 App 컴포넌트라고도 부를 수 있다. 버튼 하나가 컴포넌트가 될 수 있고, 버튼을 모아둔 영역이 컴포넌트가 될 수도 있다. 버튼 하나를 만들었을 때 이 버튼 코드를 '여러 페이지에서 사용 가능하다'는 뜻.

 

 

 


 

 

 

속성(Props)

 

 

  속성은 쉽게 말해 컴포넌트에 데이터를 전달하는 것. 그 전달 과정은 키와 벨류의 형태다. <Text>태그엔 numberOfLines라는 속성이 있었고 말 줄임표 효과를 주었었다. <Image>태그엔 resizeMode란 속성이 있었고 이미지가 영역을 차지하는 방식을 나타냈었다.  이 모든 속성들은 공식문서에 나와있고, 해당 엘리먼트들이 태어날 때부터 가지고 있는 속성이다.

 

  이를테면, <Card/> 컴포넌트를 만들었다고 가정했을 때 우리가 부여하면 부여하는대로 속성이 되는 것이다. 예를 들어 Card를 사용하는 곳에서 <Card image={'이미지 주소'}/>라고 속성을 써 넣었다면 이 <Card/>는 image라는 속성 이름에 {'이미지 주소'} 값을 갖게 되는 것. 즉 키와 벨류의 값을 갖게되는 거고 이렇듯 속성을 부여받은 컴포넌트에서 해당 속성 값을 받아서 사용할 수 있다는 것.

 

  컴포넌트에 속성(데이터)을 부여해주어 전달할 땐, 키와 벨류(content={content})형태로 전달해줘야 하며, 컴포넌트를 반복문 돌릴 땐 컴포넌트가 고유하다는 것을 표현하기위해, map에서 나오는 인덱스(i)를 key = {i} 속성 전달 형태로 꼭 넣어줘야 한다.

 

 

 

 


 

 

 

상태(State, useState)

 

 

  컴포넌트는 저마다 데이터를 보유하고 관리할 수 있다. 데이터라고 불러도 되지만, 리액트에서는 컴포넌트에서 보유/관리되는 데이터를 '상태'라고 부른다. 리액트에서 상태(state)는 리액트 라이브러리에서 제공해주는 useState로 생성하고 setState 함수로 정/변경할 수 있다.

 

  리액트는 특이한 점이 있다. 우리가 만드는 화면은 데이터에 따라 변경된다. 또 아무데이터가 아니라 이 상태(state)로 관리되는 데이터가 변경되면 화면이 바뀌게 된다.

 

 

  이 공식은 '사용자 화면(UI)은 컴포넌트(component)에 어떤 데이터(state)가 주입되고 변경되냐에 따라 변화된다'는 것을 뜻한다. 고로 state는 컴포넌트에서 관리되는 상태.

 

 

 

 

 


 

 

 

useEffect

 

 

  useEffect는 화면이 그려진다음 가장 먼저 실행되는 리액트 기본 제공 함수다.

 

 

  보통 useEffect는 데이터를 준비할 때 사용한다. 데이터를 준비한다는 것은 데이터를 서버로부터 혹은 어디선가로부터 받은 후 상태(state)에 반영한다는 것을 의미.

 

  1. 화면이 그려진다.
  2. useEffect가 데이터를 준비.
  3. 상태 데이터가 업데이트되었으니 화면이 다시 그려짐.

 

  그러나 useEffect를 사용시 오류가 발생하는 가장 큰 이유가 있는데 그 이유는 대부분 이런 절차로 발생한다.

 

  1. 화면이 그려진다.
  2. useEffect가 데이터를 state에 useState를 이용하여 업데이트.
  3. 상태(state)가 변경되었으니 화면이 다시 그려짐.

 

  원인은 1번에서 발생한다. 상태(state)에서 설정한 키 값에 접근해 데이터를 꺼낸 후 map으로 반복문을 돌리려했으나 state에 준비된 데이터가 처음부터 없었기 때문. useEffect를 거쳐야 state에 데이터가 담기는데 아직 빈 상태이기에 오류가 나는 것.  해결방안으로는 로딩화면을 만들어주는 방법이 있다.

 

 

 

 


 

 

 

Expo가 제공해주는 기능들

 

 

 

  Expo SDK. 일명 Expo에서 제공해주는 앱 기능 도구들을 개발할 때 여기에서 확인할 수 있다. 나에게 필요한 기능들이 있는지 목록을 한번 살펴보고, 원하는 기능을 선택해서 적용하면 끝.

 

링크 : https://docs.expo.dev/versions/latest/

 

API Reference - Expo Documentation

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

docs.expo.dev

 

 

 

 


 

 

 

Expo에서 제공되는 상태 바(StatusBar) 기능

 

 

 

  아래와 같이 vscode에서 터미널을 분할시킨다. 터미널 좌측은 서버 전원 담당/ 터미널 우측은 필요한 라이브러리들을 설치할 때  명령어를 입력하는 장소로 분할해서 사용하면 편리하다.

 

 

 

 

  Expo 상태 바 기능을 설치하기 위해 해당 명령어를 입력해준다 -> expo install expo-status-bar

 

 

 


 

 

  그런가하면 스택네비게이션 기능을 넣어줄 수도 있다. 스택네비게이션이란 앱에 페이지 개념을 입혀주고 웹 사이트를 이용하듯, 앱에서 우리가 만든 컴포넌트들을 페이지화 시키고 해당 페이지끼리 이동을 가능하게 해주는 라이브러리다.

 

 

 

  이 또한 쉽게 페이징을 도와주는 외부 라이브러리를 가져다 사용한다.

 

상태 바 설치코드 입력 -> yarn add @react-navigation/native

추가코드 입력 -> expo install react-native-screens react-native-safe-area-context react-native-gesture-handler

 

 

 

컴포넌트를 페이지화 시키는 스택 네비게이션은 다음과 같다.(아래그림 참고)

 

  1. 우리가 페이지처럼 만든 컴포넌트를 감싸 페이지로 만들어줌.
  2. 이렇게 만든 여러 페이지를 책갈피 기능을 하는 스택 네비게이터에 모두 등록.
  3. 페이지는 Stack.Screen이라 부르며, 책갈피는 Stack.Navigator라 부름.

 

 

  페이지를 이동시키려면, 책갈피가 페이지들에게 부여해준 페이지 이동 기능을 사용해야 한다. Stack.screen에 등록된 모든 페이지 컴포넌트들은 navigation과 route라는 딕셔너리(객체)를 속성으로 넘겨 받아 사용할 수 있다.

 

데이터 없이 페이지 이동하기
navigation.navigate("DetailPage")

데이터 가지고 페이지 이동하기
navigation.navigate("Detail",{
  title: title
})

 

 

   페이지 내용을 공유하려면 아래와 같이 Share 함수를 만들어 간단히 공유를 할 수 있다.

 

import { Share } from "react-native";

const share = () => {
        Share.share({
            message:`${tip.title} \n\n ${tip.desc} \n\n ${tip.image}`,

 

 

  또한, 앱 안에서 외부 링크를 여는 기능은 Linking을 이용할 수도 있다.

 

 

import * as Linking from 'expo-linking';

const link = () => {
        Linking.openURL("https://spartacodingclub.kr")

 

 


 

 

 

3주차 끝 그리고 숙제...👾

 

 

 

1. 어바웃 화면 페이지화 시키고 버튼 추가하기

 

 

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

export default function AboutPage({ navigation, route }) {
  const aboutImage =
    "https://storage.googleapis.com/sparta-image.appspot.com/lecture/about.png";

  useEffect(() => {
    navigation.setOptions({
      title: "소개 페이지",
      headerStyle: {
        backgroundColor: "#1F266A",
        shadowColor: "#1F266A",
      },
      headerTintColor: "#fff",
    });
  }, []);
  return (
    <View style={styles.container}>
      <StatusBar style="light" />
      <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: 20,
    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",
  },
});

 

 

 

2. Stacknavigator 사용해서 꿀팁찜 페이지 그려보기

 

 

 

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

//MainPage로 부터 navigation 속성을 전달받아 Card 컴포넌트 안에서 사용
export default function LikeCard({ content, navigation }) {
  return (
    //카드 자체가 버튼역할로써 누르게되면 상세페이지로 넘어가게끔 TouchableOpacity를 사용
    <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>
  );
}

const styles = StyleSheet.create({
  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",
  },
});

 

 

 

 

 


 

 

 

끝으로.

 

 

  우린 답을 찾을 것이다. 늘 그랬듯이... 이번 주차 때는 하도 얼타서 오류가 많았다... 그때마다 즉문즉답에 바로바로 물어봐서 해결할 수 있었다. 똑같이 한다고 했는데도 불구하고 오류가 발생하는 거 보면 나도 참 대단한듯(?)

 

 

 

 

LIST