[RN] 사전준비

민디·2024년 5월 8일

RN

목록 보기
2/4
post-thumbnail

이 글은 인프런 강의를 듣고 정리하여 작성된 내용입니다.

안녕-하요! 민디입니다! 🤭
정말 오랜만이네요! 벌써 5월이라니 시간 참 빠르지 않나요?

자 그럼 5월의 기운에 힘입어 오늘은 본격적으로 React Native 를 시작하기에 앞서 사전 준비를 해보려고 합니다!

저번에 React Native 의 개념과 원리 환경 세팅 다 알아봤는데, 사전에 또 알아볼게 뭐가 있냐구요?
혹시 저번 글 기억 나시나요? 이런 말이 있었습죠

React Native 는 진입 장벽이 낮으며 이해하기가 쉬우나, 위에서 이야기했듯이 HTML, CSS, JS, ES6, React 등 많은 선수 지식이 필요합니다. (근데 진입 장벽이 낮다고..?)

어후 미리 알아야할 게 이렇게나 많은데 진입 장벽이 낮다니, 눈물이 앞을 가리네요

그래서 오늘은 요러한 지식들을 아주 짧게 나마! 이 정도만 알아도 React Native 할 수 있어! 정도만 알아보려고 합니다!

제가 지금부터 작성하는 내용은 강의를 보고 정리하여 작성한 내용이기 때문에 진짜 발만 담갔다 빼는 수준입니다!
그럼 레츠기릿😎

ECMAScript 6 (ES6)

ES6 은 ECMAScript 6의 약자로 자바스크립트의 개정 버전입니다. 개발자의 생산성을 향상시키고 코드를 더욱 명확하고 간결하게 만들기 위한 다양한 새로운 기능들을 제공한다는데.... 🤔 어찌되었든 자바스크립트의 진화 버전 이라고 생각하면 되겠지요?

기존 자바스크립트의 var 를 사용하면 문제점이 있습니다.
function 단위의 scrop 을 가지며 중복된 변수명이 존재해도 에러가 발생하지 않는다는 문제점이죠.

그래서 이러한 문제를 해결하기 위해 ES6이 나왔다고 합니다!
var 대신 let 을 이용하자!
let 을 이용할 경우 변수명이 중복되면 에러가 발생합니다. 그러므로 var 보다는 let 의 사용이 권장됩니다.

또한 const 를 이용해 변하지 않는 수에 대한 선언을 할 수 있습니다.
(다만 객체나 배열의 요소 수정은 가능합니다.)

const drinks = {};
drinks.caffe = 'latte';
drinks.lemon = 'ade';

console.log(drinks)

// { caffe: 'latte', lemon: 'ade' }

const arr = [1,2,3,4,5,6];
arr[0] = 100;
arr[4] = 500;

console.log(arr)

// [ 100, 2, 3, 4, 500, 6 ]

위 코드에서 볼 수 있듯이 drinksconst 로 선언했지만 객체 형식이기 때문에 내부 요소는 수정이 가능한 것을 볼 수 있습니다.
마찬가지로 배열의 경우에도 arrconst 로 선언되었지만 요소 값을 수정할 수 있죠!

그렇다면 ES6 에서 자주 쓰이는, 핵심적인 문법은 무엇일까요?
지금부터 같이 한 번 알아봅시다!

String Literal

문자열과 변수를 편하게 다룰 수 있게 해주는 문법입니다.
기존에는 변수와 문자열을 이어주기 위해 다음과 같이 작성하였습니다.

const value1 = 'Hello';
const value2 = 'World';
const value3 = value1 + ' ' + value2 + '!!!';

+' ' 를 이용해 연결을 해줘야 한다니.. 만약 안의 내용이 많아진다면 보기도 엄청 불편하겠죠?
이러한 불편함을 해결해주기 위해 String Literal 이 등장했습니다!
사용방법은 다음과 같습니다.

const litVal = `${value1} ${value2}!!!`

어때요, 더욱더 간편해졌죠?

for...of 반복문

기존에 많이 사용하던 for-in 이라는 반복문이 있었습니다.
for-in 은 객체의 키 값에만 접근이 가능하며, value 값에는 접근이 불가능합니다.

let array = [10, 20, 30, 40];

for (let val in array) {
	console.log(array[val]);
}

for-of 문은 value 값에 접근이 가능하지만 모든 객체 상대로 사용할 순 없습니다. 키 값이 저절로 생기는 배열 같은 객체여야지만 사용이 가능합니다.

for (let val of array) {
	console.log(val)
}

let obj = {
	a: 1,
	b: 2.
	c: 3
} // -> for of 를 사용할 수 없다 (키 값이 없기 때문에) , for in 을 사용하면 된다.

Rest Operator

모든 나머지 인자를 표준 자바스크립트 문법으로 대체하기 위한 문법입니다. 이 친구를 사용하여 나머지 인자를 배열로 대체해줍니다.
... 을 이용하여 사용할 수 있습니다.

function printNums(num1, num2) {
	console.log(num1, num2);
}

printNums(1, 2, 3, 4, 5)

// 1 2

// arguments → 함수로 전달된 모든 인수를 포함하는 객체
function printNums(num1, num2) {
	console.log(arguments);
}

printNums(1, 2, 3, 4, 5)

// [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 }

function printNums(num1, ...num2) {
	console.log(num1, num2);
}

printNums(1, 2, 3, 4, 5);

// 1 [ 2, 3, 4, 5 ]

Rest Operator 는 함수를 호출 할 때 인수로 사용할 수도 있고, 배열, 객체 안에 들어갈 수도 있습니다.
함수에서 사용할 경우는 다음과 같이 사용합니다.

// 배열의 요소를 함수의 인수로 사용하고자 할 때  → apply
sum.apply(null, arr);

// spread operator
sum(...arr2);

let arr3 = [20, 30];
sum(10, ...arr3, 40, 50);

배열에서 사용하고자 할 때는 다음과 같이 사용합니다.

let face = ['eyes', 'nose', 'mouth'];
let head = ['hair', ...face, 'ears'];

console.log(head)

// [ 'hair', 'eyes', 'nose', 'mouth', 'ears' ]

또한 배열을 복사할 때도 사용할 수 있습니다.
배열을 복사할 때 배열로 선언된 변수를 그대로 담아줘도 되지만 오리지널 배열이 복사된 배열의 수정에 의해 영향을 받을 수도 있기 때문에 주의해야합니다.

let arr3 = [1, 2, 3];
let arrCpy = [...arr3];

console.log(arrCpy)

// [ 1, 2, 3 ]


let arrCpy = [arr3];
// 도 동일한 결과 그러나 오리지널 배열이 복사된 배열의 수정에 의해 영향을 받을 수도 있다.

arrCpy.push(4);
console.log(arr3);
console.log(arrCpy);

// [ 1, 2, 3, 4 ]
// [ 1, 2, 3, 4 ]

객체에서 사용할 때는 다음과 같이 사용합니다.

let drinks = {
    caffe: 'latte',
    coca: 'cola'
};

let newDrinks = {
    lemon: 'tea',
    orange: 'juice',
    ...drinks
};

console.log(newDrinks);

// { lemon: 'tea', orange: 'juice', caffe: 'latte', coca: 'cola' }

Arrow Function

직역하여 화살표 함수라고 합니다. 표현식의 결과값을 반환하는 표현식 본문입니다.
다음과 같이 사용할 수 있습니다.

let array = [1, 2, 3, 4, 5];
// map = for문 
// 배열 객체 내장 함수 (파라메터로 값이 전달) -> 각 요소가 input 함수에 의해 새로운 배열로 리턴
let twice = array.map(v => v * 2)

console.log(twice);

// [ 2, 4, 6, 8, 10 ]

Arrow Function 의 특징은 다음과 같습니다.

  • 간결성 : 함수 키워드 function 대신 화살표 => 를 사용하여 간결하게 표현할 수 있습니다.
  • 명확성 : 함수 본문이 한 줄인 경우 중괄호 생략이 가능합니다.
  • this 바인딩 : 함수 내부에서 this 는 정의된 컨텍스트를 참조합니다.
  • lexical scoping : 블록 범위 내 변수에 접근이 가능합니다.

하지만 Arrow Function 을 사용할 때 주의점이 있습니다.

  • 생성자 함수로 사용할 수 없습니다.
  • 상속을 위한 super 키워드를 사용할 수 없습니다.
  • arguments 객체를 사용할 수 없습니다.

Class

자바스크립트에서는 함수 처럼 사용됩니다.
constructor 를 이용해 클래스 인스턴스를 생성하고, 생성한 인스턴스를 초기화 시킵니다.
여기서 인스턴스랑 클래스를 구성하기 위한 껍데기 입니다.

class Person {
    constructor(region_, gender_) {
        this.region = region_;
        this.gender = gender_
    }

    greetings(val = '안녕') {
        console.log(val)
    }
}

// new 연산자가 constructor 호출하면서 파라메터를 전달해주고 초기값을 세팅
let korean = new Person('Korea', 'male')
console.log(korean)

// Person { region: 'Korea', gender: 'male' }

korean.gender = 'female';
console.log(korean)

// Person { region: 'Korea', gender: 'female' }

korean.greetings();

상속을 하고 싶은 경우 extends 키워드로 구현합니다.
부모 클래스와 자식 클래스에 동일한 이름의 함수가 있다면 부모 클래스의 함수는 호출되지 않으며 자식 클래스의 함수를 따릅니다.

class American extends Person {
    constructor(region_, gender_) {
		    // 부모 클래스에 있는 초기화 룰을 따르겠다.
        super(region_, gender_)
        this.language = language_
    }
    
     greetings(val = 'hello') { // 생략 가능 -> 생략 후 호출 시 부모 클래스의 greetings 출력
       console.log(val)
    }
    
    let american = new American('USA', 'female', 'english');
		console.log(american)
}

// American { region: 'USA', gender: 'female', language: 'english' }

여기까지가 일단 알아두면 좋은 ES6 의 문법들입니다.
그럼 이제 React Native 를 하기 위한 필수 선수 지식 중 하나인 React 에 대해 간단하게 알아볼까요?

React

React 는 UI(User Interface) 를 개발하기 위한 자바스크립트 라이브러리입니다.
텍스트, 버튼과 같은 화면을 구성하는 뷰를 만들어주며 페이스북에서 개발하고 관리합니다.

그렇다면 앞으로 React Native 에서 많이 사용할 React 문법을 몇 개 알아봅시다! 🫡

State

컴포넌트에서 렌더링 되는 데이터를 담고, 유지 관리하는 자바스크립트 객체입니다. 클래스 컴포넌트 안에서 사용 가능하며, 함수형 컴포넌트에서는 React Hook 이란 친구를 사용해 사용할 수 있습니다.
아래 예제는 클래스형 기준입니다!

setState

state 는 값을 직접 바꿔주면 화면을 다시 렌더링하지 않기 때문에 값이 변경되지 않습니다. 또한 state 는 쉽게 변경되면 안되기 때문에 setState 를 이용해 값을 변경합니다.

changeState = () => {
	this.setState({
		sampleText: 'Text Changed!'
	})
}

<Text onPress = {this.changeState}>
	{this.state.sampleText}
</Text>

또한 state 는 비동기성으로 데이터의 값을 변경할 때 현재 버전을 카피한 뒤 업데이트를 진행해야합니다.

state = {
	sampleText: 'Hello World',
	sampleBoolean: true,
	sampleNum: 1
}

onAdd = () => {
	this.setState({
//		sampleNum: sampleNum + 1 // 에러
	})
	
	// 현재 버전을 카피하고 업데이트를 진행해야 한다.
	// prevState 를 이용해 현재 state 가 가지고 있는 num 을 이용한다.
	this.setState(prevState => {
		return {
			sampleNum: prevState.sampleNum + 1
		}
	}
}

그렇다면 state 를 함수형 컴포넌트에서 사용하려면 어떻게 해야할까요? 이 때 사용할 수 있는 것이 React Hook 이란 기능입니다.
React Hook 에 대해서 따로 작성해볼 예정이지만 state 부분만 간단하게 설명하자면,

기존 state 를 이용해 클래스형 컴포넌트에서 사용했다면, 함수형에서는 useState 를 이용합니다.
선언 방법과 사용 방법은 다음과 같습니다.

import React, { useState } from 'react';

const [state, setState] = useState('')

const changeState = () => {
 	setState('hi');
}

<Text onPress = {changeState}>
	{state}
</Text>

조금 더 간단해진 것 같죠?

Props

Props 는 read-only 입니다. 말 그대로 수정과 변경이 불가능한 읽기 전용 프로퍼티입니다.
부모 자식 관계가 형성되어야 의미가 있으며, React, React Native 는 데이터 흐름이 일방통행이기 때문에 부모와 자식의 관계만이 존재합니다.
자식은 부모한테 props 라는 데이터를 받고, 자식에서 수정되지 않고 그대로 사용됩니다.
부모가 가지고 있는 정보가 어떤 자식이든 똑같이 쉬운 방법으로 전달할 수 있다는 장점이 있습니다.
View 를 이용해 넘겨준 값을 props 를 통해 받을 수 있습니다.

<View style={styles.background}>
  <PropsChild sampleText={this.state.sampleText} changeState={this.changeState}/>
</View>


const PropsChild = (props) => {
    return (
        <View>
            <Text onPress={props.changeState}>{props.sampleText}</Text>
        </View>
    )
};

요기까지만 알아도 React Native 를 사용하는데 문제는 없을겁니다! 물론 나중에 좀 더 하게 되면 더 많은 지식을 필요로 하지만 저희에게는 구글햄이 있잖아요? 🥴

이제 마지막으로 React Native 에 대해서 알아보려고 합니다! 마지막까지 힘내서 가보자구요

React Native

React Native 프로젝트를 생성하게 되면 가장 먼저 볼 수 있는 코드가 index.js 입니다. 앱의 메인 입구를 담당합니다!

AppRegistry.registerComponent(appName, () => App); // 앱을 시작하는 곳

여기서 appName 은 앱 이름이며, app.json 파일에서 수정할 수 있습니다.
App 은 가장 처음 보여지는 화면입니다.

그렇다면 이제 본격적으로 React Native 의 주된 컴포넌트들을 살펴봅시다!

View, Text

App 안에 화면을 렌더링하는 함수가 있고, 그 안에 리턴되는 것들이 화면을 구성하게 됩니다.
ViewText 는 react-native 모듈에서 import 하여 가져온 것이며, View 는 다른 컴포넌트들을 감싸주는 역할을 합니다. 그래서 주로 가장 상단에 View 를 사용하는 경우가 많죠.
위치나 색, 크기 등의 스타일을 주기 위해서는 별도의 작업이 필요합니다. 스타일에 대해서는 바로 다음에 알게 되실겁니다!

render() {
    return (
      <View>
        <Text>Hello World!</Text>
      </View>
    );
  }

Style

스타일을 지정하는 방법에는 두 가지가 있습니다. 바로 인라인 스타일링과 StyleSheet 를 이용하는 것입니다.
먼저 인라인 스타일링 같은 경우에는 {{ }} 를 이용해 태그 안에 style 을 지정합니다.
각 중괄호는 순서대로 JSX, 객체 의 의미를 가집니다.

<View style={{ // 화면을 채우는 컨테이너 역할
  backgroundColor: 'green',
  marginTop: 50, // pixel 단위 x, 디바이스의 고유 단위
  height: '100%'
}}>
  <Text>Hello world</Text>
</View>
      
// margine -> View 가 다른 컴포넌트와의 간격
// padding -> View 내부 요소가 View 와의 간격

style 은 float 와 같은 부동소수점을 이해하지 못하기 때문에 정수로 작성해줘야합니다.

두 번째 StyleSheet 를 이용하는 방법이 있습니다.
여러 태그가 동일한 스타일을 사용한다면 따로 빼서 동일하게 지정해 줄 수 있습니다.

<View style={styles.mainView}>
  <Text>Hello world</Text>
</View>

const styles = StyleSheet.create({
  mainView: {
    backgroundColor: 'green',
    paddingTop: 50, // pixel 단위 x, 디바이스의 고유 단위
    flex: 1,
    alignItems: 'center', // 수평정렬
    justifyContent: 'center' // 수직정렬 
  }
})

// flex : 화면을 채우는 컴포넌트들간에 차지하는 영역의 비율을 나타내는 지표
// A 뷰가 flex 가 1이고, B 뷰가 flex 3 이라면, A 뷰는 화면의 4/1 을 차지하며, B 뷰는 화면의 4/3 을 차지한다.

Touch Event

JSX 컴포넌트를 return 하기 때문에 새로운 컴포넌트를 만들 때 () 를 통해서 만들어 줍니다.

exampleFunction = () => {

} // return 되는 JSX 컴포넌트가 없다.

exampleFunction = () => (

) // return 되는 JSX 컴포넌트가 있다.

// JSX -> Javascript XML -> 자바스크립트 확장 문법
// const example = <tag>hello world</tag>

Touch Event 가 주로 쓰이는 버튼을 만들기 위한 컴포넌트가 몇 가지가 있습니다.

TouchableOpacity

뷰가 터치에 반응하도록 합니다. 터치를 할 때 버튼이 투명해지는 효과가 있습니다.

<TouchableOpacity
    style={styles.header}
    onPress={() => alert('hello')}
>
    <View>
        <Text>{props.name}</Text>
    </View>
</TouchableOpacity>

TouchableWithoutFeedback

터치를 할 때 버튼이 투명해지지 않고 동일합니다. 뷰에 아무런 변화를 일으키지 않기 때문에 스타일을 지정할 경우 내부 뷰에 지정해줘야합니다.

<TouchableWithoutFeedback
    onPress={() => alert('hello')}
>
    <View style={styles.header}>
        <Text>{props.name}</Text>
    </View>
</TouchableWithoutFeedback>

onPress 와 같이 어떤 식으로 터치를 했는가에 따라 다른 액션을 줄 수 있습니다.

  • onPress : 터치했을 경우
  • onLongPress : 오래 터치했을 경우
  • onPressIn : 터치할 때 바로 반응합니다
  • onPressOut : 터치에서 손을 떼면 반응합니다.

Button

위에서 이야기한 컴포넌트가 아닌 기본 제공해주는 Button 을 이용해 만들게 되면 iOS 와 Android 의 모양이 다릅니다.
그렇게 때문에 버튼의 모양을 동일하게 만들어 주고 싶다면 TouchableOpactiy 또는 TouchableWithoutFeedback 를 이용하는 것이 좋습니다.

ScrollView

스크롤이 필요할 때 사용합니다. ScrollView 태그 안 요소들이 스크롤이 되게 해줍니다.

<ScrollView style={{width: '100%'}}>
  <NumList num={this.state.random} delete={this.onNumDelete} />
</ScrollView>

ScrollView 에는 다양한 속성들이 있습니다.

  • onMomentumScrollBegin : 스크롤이 움직이기 시작했을 때를 감지합니다. 저절로 움직이는 시점이며 스크롤 했다가 떼었을 경우 발생합니다.
  • onMomentumScrollEnd : 스크롤의 움직임이 멈췄을 경우를 감지합니다.
  • onScroll : 스크롤이 감지되었을 경우입니다. 1px 이라도 움직이면 실행됩니다.
  • onContentSizeChange : 사이즈가 바뀔 때 트리거됩니다. widthheight 를 인자로 갖습니다.
  • bounces : 스크롤에 바운스 효과를 줍니다 defaulttrue 입니다.

TextInput

말 그대로 텍스트를 입력할 수 있는 컴포넌트입니다.

<TextInput
    value={this.state.myTextInput}
    style={styles.input}
    onChangeText={this.onChageInput}
    multiline={true} // 글자수가 많아지면 개행
    maxLength={100} // 글자수에 제한
    autoCapitalize='none' // none = 대문자 자동 수정 안함
    editable={false} // false = disable
/>

Image

이미지를 표시할 때 사용하는 컴포넌트 입니다. 이미지를 불러오는 방법에는 두 가지가 있는데, 로컬에 있는 이미지를 가져올 경우와 서버에 있는 이미지를 가져올 경우입니다.
먼저 로컬에 있는 이미지를 가져올 때는 import 를 하여 미리 선언해둔 뒤 가져오거나 require 를 이용하여 표시합니다.

import Saida from './assets/images/saida.png';

<Image
	style={styles.image}
	source={Saida}
	// source={require('./assets/images/saida.png')}
	resizeMode='contain' 
	// cover = default, 주어진 크기만큼 채우는 것
	// contain = 주어진 공간 내에서 원본 사진을 다 보여준다
/>

서버에 있는 이미지를 가져올 경우 주로 uri로 넘어오기 때문에 uri 를 이용해 표시할 수 있습니다.

// https://picsum.photos/id/237/200/300

<Image
	style={styles.image}
	source={{uri: 'https://picsum.photos/id/237/200/300'}}
	resizeMode='contain' 
	// cover = default, 주어진 크기만큼 채우는 것
	// contain = 주어진 공간 내에서 원본 사진을 다 보여준다
	onLoadEnd={() => alert('Image Loaded!')} // 이미지 로딩이 끝났을 때 트리거
/>

여기까지 기본적으로 알아두면 좋은 React Native 의 컴포넌트들이었습니다!
물론 이것보다 더 많은 컴포넌트들이 숨어있지만 당장 React Native 를 시작하기에는 문제가 없을 것이라 생각이 됩니다!

길고 긴 이야기가 되었지만 이제 시작하시는 분들에게 조금이나마 도움이 되었으면 좋겠습니다!

저는 지금도 많고 많은 시행착오를 겪어가며 적응 중에 있습니다 🥲

그러니 제 스스로의 공부를 위해서라도 기초부터, 이슈, 알게된 내용 등을 정리해서 아카이빙할 예정이니 앞으로도 함께해보자구요! 아자아자
그럼 또 다음에 보아요!

모두들 안녕-쟈네-👋

profile
이(this || 異) 세계에서 개발자를 하고 있습니다.

0개의 댓글