React Native day1

KJK·2022년 9월 6일
0

이 포스트는 공식문서0.70v를 읽으면서 작성했습니다.
잘 모르겠는 부분은 원문도 첨부했습니다.

Introduction

전제 조건

javascript의 이해가 필요합니다.

React Native란?

React Native는 React와 앱 플랫폼의 기본 기능을 사용하여 Android 및 iOS 애플리케이션을 빌드하기 위한 오픈 소스 프레임워크입니다.

Core Components and Fabric Components

Views

View는 모바일 ui에서 기본 단위입니다.
작은 직사각형 요소로 text, image, respond to user input가 존재합니다.
아주 작은 버튼이나 텍스트도 하나의 View입니다.
일부 View는 다른 View들을 포함할 수 있습니다.
ios android views
출처: React Native 공식문서

Febric Components

Android는 Java이나 Kotlin, iOS는 Swift나 Objective-C언어를 이용하여 Native app 개발을 합니다.
반면 React Native에서는 javascript, react를 이용해서 각종 View들을 호출할 수 있습니다.
( react naive로 작성한 View코드가, native View로 바뀌는 것이 아닙니다. )
런타임에 react native가 component들로 각 환경에 맞는 view들을 생성합니다.
이런 플랫폼 지원 component를 Fabric Components라 합니다.

Febric은 ReactNative렌더러 이름입니다.
Febric Components는 Febric으로 렌더링된 요소의 이름입니다.

React Native에서는 필수적이거나 실행하는데 필요한 Febric Components를 제공합니다.
이것을 Core Components라 부릅니다.

원문: React Native also lets you build your own Fabric Components to suit your app’s unique needs
아마도 특정 플랫폼를 위한 Fabric Components를 구현할 수 있다는 의미로 해석된다.

또한 React Native에는 번창하는 커뮤니티가 있습니다.
Native Directory에서 커뮤니티에서 만들고 있는것을 볼 수 있습니다.

Core Components

React Native에서는 필수적이거나 실행하는데 필요한 Febric Components를 제공합니다.
이것을 Core Components라 부릅니다.
모든 Core Components

마지막으로 React Native는 React구조를 따르고 있으므로 React의 핵심개념을 알아야 합니다.
components, jsx, props, state를 알고 있다면 넘어가세요.
React가 처음이라면 React Fundamentals

diagram react native comonents
출처: React Native 공식문서

Handling Text Input

TextInput은 유저의 text입력을 받는 Core Component입니다.
onChangeText 텍스트가 바뀔때 마다 함수호출
onSubmitEditing 코드 제출시 작동

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

const PizzaTranslator = () => {
  //text 내용이 매 입력마다 바뀌기 때문에 state로 저장한다.
  const [text, setText] = useState('');
  return (
    <View style={{padding: 10}}>
      <TextInput
        style={{height: 40}}
        placeholder="Type here to translate!"
        onChangeText={newText => setText(newText)}
        {/* TextInput의 값이 변경될 때 마다 호출되는 콜백함수 */}
        defaultValue={text}
      />
      <Text style={{padding: 10, fontSize: 42}}>
        {text.split(' ').map((word) => word && '🍕').join(' ')}
        {/* 여기서 번역이 일어난다. */}
      </Text>
    </View>
  );
}

export default PizzaTranslator;

Using a ScrollView

ScrollView는 여러개의 Components와 Views를 포함할 수 있는 scroll container입니다.

원문: The scrollable items can be heterogeneous, and you can scroll both vertically and horizontally (by setting the horizontal property).
스크롤이 화면 방향에 따라 이질적일 수 있다. 그러므로 스크롤 사용시에 수평이나 수직 방향설정이 필요할 것이다.

pagingEnabled 를 통해서 스크롤가능 여부를 설정할 수 있습니다.
Android에서 가로스크롤 설정은 ViewPager
IOS에서는 줌인 줌아웃이 가능합니다. 관련 props로는 maximumZoomScaleminimumZoomScale가 있습니다.

ScrollView는 좁은 화면에 다양한 View가 들어가는 곳에 적합합니다.
ScrollView가 렌더링되면, ScrollView 안에 들어가서 아직 보이지 않는 View들도 모두 렌더링 됩니다.

화면에 담기지 않을정도로 긴 Item들이 있는 경우는 FlatList를 추천합니다.
( 참고로 Item은 비슷한 구조의 데이터를 갖는 View나 Component를 지칭하는것 같다. )

예제코드는 View 대신 ScrollView로 감싸져 있는 것이 전부라서 생략했습니다. 예제코드를 보실 분은 Using a ScrollView를 확인해 주세요.

Using List Views

React Native에서는 list of datas를 표시하기 위한 Component를 제공합니다.
일반적으로는 FlatListSectionList가 있습니다.

FlatList는 변하지만 유사한 데이터 및 구조를 지닌 scrolling list입니다.
시간에 따라 항목의 수가 변경되는 list에 적합합니다.
ScrollView와 달리 FlatList는 화면에 보여지는 요소들만 렌더링이 발생합니다.

원문: The FlatList component requires two props: data and renderItem. data is the source of information for the list. renderItem takes one item from the source and returns a formatted component to render.
FlatList는 두 개의 props를 가집니다. data, renderItem
예제 코드를 보는 것이 이해가 쉬워 아래 코드를 첨부합니다.
참고로 아래 예제는 renderItem에 하드코딩이 되어있지만, Component를 이용해서 별도로 분리할 수 있습니다.

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

const styles = StyleSheet.create({
  container: {
   flex: 1,
   paddingTop: 22
  },
  item: {
    padding: 10,
    fontSize: 18,
    height: 44,
  },
});

const FlatListBasics = () => {
  return (
    <View style={styles.container}>
      <FlatList
        data={[
          {key: 'Devin'},
          {key: 'Dan'},
          {key: 'Dominic'},
          {key: 'Jackson'},
          {key: 'James'},
          {key: 'Joel'},
          {key: 'John'},
          {key: 'Jillian'},
          {key: 'Jimmy'},
          {key: 'Julie'},
        ]}
        renderItem={({item}) => <Text style={styles.item}>{item.key}</Text>}
      />
    </View>
  );
}

export default FlatListBasics;

IOS의 UITableViews와 유사하게 Section별로 나뉘어진 list를 표현하려면 SectionList를 참고하세요.

일반적으로 서버로부터 데이터를 가져올 때 주로 사용하는데, 그러려면 React Native에서의 네트워킹을 배워야합니다.

Troubleshooting

일반적인 문제 해결 바로가기

일부 문제들을 보자면,
Metro bundler가 8081 port를 이용합니다.
React Native가 WebSockets을 폴리필로 구현해서 Firebase같은 WebSockets을 필요로하는 라이브러리는 react-native 다음에 load나 require해야 합니다.

Platform Specific Code

많은 플랫폼에 재사용 가능한 코드를 사용할 것이다.
반면 플랫폼 별로 별도의 화면 구성이 필요할 경우도 있습니다.

React Native에서는 두가지 방식으로 플랫폼을 구분합니다.
Platform module, Platform-specific extensions

Platform module

앱이 실행되는 플랫폼을 감지하는 Platform 모듈을 제공합니다.

Platform.OS

string으로 플랫폼이름을 가져옵니다.

import { Platform, StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  height: Platform.OS === 'ios' ? 200 : 100
});

Platform.select()

'ios' | 'android' | 'native' | 'default'중 플랫폼에 일치하는 값을 반환합니다.
만약 키로 구현하지 않는 플랫폼을 사용중이라면 default를 가져옵니다.

import { Platform, StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    ...Platform.select({
      ios: {
        backgroundColor: 'red'
      },
      android: {
        backgroundColor: 'green'
      },
      default: {
        // other platforms, web for example
        backgroundColor: 'blue'
      }
    })
  }
});

응용: Platform.select로 어떤 값이든 가능하므로, 플랫폼별 Component 또한 다르게 구현할 수 있습니다.

const Component = Platform.select({
  ios: () => require('ComponentIOS'),
  android: () => require('ComponentAndroid')
})();

<Component />;

Platform.Version

android, ios 각각 사용 방식이 다릅니다.

Android에서 platform.Version은 숫자를 반환합니다.
Android OS Version이 아니라 Android API Version으로 되어있어 매핑된 값을 확인하려면 Android Version History를 참고하세요.

import { Platform } from 'react-native';

if (Platform.Version === 25) {
  console.log('Running on Nougat!');
}

IOS에서 platform.Version-[UIDevice systemVersion] 문자열을 반환합니다.
Version의 숫자를 감지하려면 아래 예제를 확인하세요.

import { Platform } from 'react-native';

const majorVersionIOS = parseInt(Platform.Version, 10);
if (majorVersionIOS <= 9) {
  console.log('Work around a change in behavior');
}

Platform-specific extensions

플랫폼 별 코드가 복잡할 경우, 별도의 파일로 나누는 방식을 고려해야 합니다.
.ios..android.로 확장자를 바꾸면, Component를 불러올 때 플랫폼별로 다른 Component를 호출할 수 있습니다.

프로젝트가 다음처럼 존재하면

BigButton.ios.js
BigButton.android.js

Component 사용할때 다음처럼 사용할 수 있습니다.

import BigButton from './BigButton';

Native-specific extensions (i.e. sharing code with NodeJS and Web)

원문: You can also use the .native.js extension when a module needs to be shared between NodeJS/Web and React Native but it has no Android/iOS differences.
NodeJS/Web과 ReactNative에서 공유하는 module이 필요할 때, .native.js 확장자를 이용할 수 있습니다. 단 IOS와 Android에서는 차이가 없어야 합니다.

ReactNative와 ReactJS에서 코드를 공유할 때 특히 유용합니다.

Container.js 
# picked up by Webpack, Rollup or any other Web bundler
# Webpack이나 Rollup같은 번들러는 Container.js를 선택합니다.

Container.native.js 
# picked up by the React Native bundler for both Android and iOS (Metro)
# Metro같은 ReactNative용 번들러는 Container.native.js를 선택합니다.

.native확장자 없이 호출할 수 있습니다.

import Container from './Container';

원문: Pro tip: Configure your Web bundler to ignore .native.js extensions in order to avoid having unused code in your production bundle, thus reducing the final bundle size.
Pro tip: production에서 번들 사이즈를 줄이기 위해, Web 번들러의 경우 .native확장자를 무시 합니다.

More Resources

developer workflows, shiping to app stores, i18n, security등 배울게 아직 많습니다.

더 많은 내용은 여기에 있습니다.

profile
찍먹하자

0개의 댓글