React-Native
로토
웹 개발자가 시도해본
스마트스터디
오늘 공유할 내용
- what is react-native?
- 써본 후기
- 그외 특징들
쉽게 말해서 react로
모바일 앱 개발하는 것
앱 개발에 숟가락 얹을 수 있겠는데..?
비슷한 기술
-
titanium
- JS Code를 이용해 네이티브 화면을 그림
- xml로 view를 표현
- Native Script
개발자의 욕심은 끝이 없고
같은 코딩을 반복한다
경험담 - instagram
경험담 - ubereats
- React/Flux SPA로 레스토랑 대시보드가 구현되어 있었음
- WebView로 래핑되어 제공
- 사운드 알람 등의 기능이 웹 기반 구현에서 좋지 않은 사용성
- 영수증 인쇄 등의 기능은 웹에서 구현하기 힘들었음
- 로직을 JS 코드에 집중
- Javascript와 Objective C, Java 간의 컨텍스트 전환 감소
- 플랫폼 고유 코드 감소로 인한 이식성 향상
- 버그 범위 축소
- JS Bundle만 재배포하여 앱 재배포 없이 업데이트 가능해짐
경험담 - airbnb
결국은 code share
Architecture
Architecture
Bridge
Native Code
JS Runtime Environment
React Native Code
iOS or Android OS
Architecture
React Native Build
node.js 로 컴파일 및 js bundle publish
Node Server
127.0.0.1:8001/index.platform.bundle.js
JS Runtime
iOS or Android Native Project
Native Project의 JS Runtime에서는
publish된 JS Bundle을 참조
Hello! React Native!
Hello! React Native!
npm install -g react-native
react-native init HelloRN
cd HelloRN
react-native run-ios // ios
react-native run-android // android
mac + iOS는 쉽게 시작 할 수 있음
mac + Android는 Android SDK setting 필요
windows 에선 Android 개발만 가능
Hello! React Native!
Live Reload
- React Web 개발환경에서 아주 편하게 쓰던 그것
- JS에 변경점이 있다면 Bundle을 새로 생성하고
해당 Bundle을 자동 reload 후 앱을 다시 렌더링 - 수동 리로드도 가능
- Android - R 두번(한영 상태 주의)
- iOS - command + R
Hot Reloading
- React Web 개발환경에서 아주 편하게 쓰던 그것(2)
- JS에 변경점이 있다면 변경된 부분만 화면을 다시 그림
- 리로드 일어나지 않음
공통점
다시 컴파일 할 필요가 없다!
UI를 빠르게 개발할 수 있다!
Platform
Supported Platforms
- iOS
- Android
- Window 10 Mobile
Detect Platform
import { Platform, View, Text } from 'react-native';
const Panel = () => (
<View style={{paddingTop: Platform.OS === 'ios' ? 20 : 0}}>
<Text>SmartStudy!</Text>
</View>
);
Platform module의 OS 파라메터 이용
Detect Platform
// app/Hello/index.ios.js
const Hello = () => (
<View style={{paddingTop:20}}>
<Text>안녕?iOS!!</Text>
</View>
);
export default Hello;
// app/Hello/index.android.js
const Hello = () => (
<View>
<Text>안녕?안드로이드!!</Text>
</View>
);
export default Hello;
index.{platform}.js
// platform에 따라 index.js가 로딩됨
import Hello from './app/Hello';
const App = () => (
<View>
<Hello />
</View>
);
export App;
App.js
Native Module
Android
- ReactContextBaseJavaModule를 상속
- getName() 메소드를 override
- 제공할 메소드에 @ReactMethod 애너테이션 붙임
public class ToastModule extends ReactContextBaseJavaModule{
private static final String DURATION_SHORT_KEY = "SHORT";
private static final String DURATION_LONG_KEY = "LONG";
public ToastModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "ToastExample";
}
@Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<>();
constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
return constants;
}
@ReactMethod
public void show(String message, int duration) {
Toast.makeText(getReactApplicationContext(), "NATIVE MESSAGE : " + message, duration).show();
}
}
Android
- ReactPackage interface를 implements
- createNativeModules에 RN으로 제공할 modules을 add
public class ToastModulePackage implements ReactPackage{
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new ToastModule(reactContext));
return modules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
Android
- MainApplication.java 의 getPackages 의 리턴 값으로 앞에서 만든 ReactPackage 구현체를 추가
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new ToastModulePackage()
);
}
Android
- NativeModules에서 꺼내서 쓰면 됨
import React from 'react';
import { View, Text, Button, NativeModules } from 'react-native';
const { ToastExample } = NativeModules;
const Hello = () => (
<View>
<Text>안녕?안드로이드!!</Text>
<Button text="누질러봐" onPress={() => ToastExample.show('눌렀니?', ToastExample.LONG)} />
</View>
);
export default Hello;
My Experience
저의 앱 개발 관련 지식
- Java & Gradle 할 줄은 압니다.
- 하이브리드 웹앱은 만들어봤습니다.
(using ionic framework, cordova) - 안드로이드는 맛만 살짝 봤습니다.
- 2.1 기준
- 사실 게임 만들어본 거라 별 도움 안 됩니다.
- Objective C와 XCode는 전혀 모릅니다.
Toy Project
- Instagram app 카피 시도
- react-native 에서의 스타일링을 익혀보기 위함
- 전형적인 CRUD + 네이티브의 기능을 체험
- Timeline
- Story + Image upload
- Camera
- Back-End는 firebase 사용
- Auth
- Storage
- Database
고민의 시작 - navigation
react-navigation
- https://reactnavigation.org/
- 공식 문서에서 언급이 되어있어서 이 모듈을 사용
- 크게 StackNavigation, TabNavigation, DrawingNavigation
- 다양한 Navigation을 조합해서 Screen간 인터랙션을 구현
styled-components
- 1회성으로 사용되는 스타일이 많아서 styled-components 사용
- https://www.styled-components.com/
Screens
- Login Screen
- Create Account Screen
- Timeline Screen
- SelectMedia Screen
- Create Story Screen
- Profile Screen
Login / Create Account Screen
- firebase의 authenification 사용
- react-native-elements 로 폼 구현
- 웹 개발과 비슷한 느낌
- LoginScreen.js code link
- CreateAccountScreen code link
Timeline Screen
- FlatList 컴포넌트 사용
- ScrollView 확장
- pull to refresh 구현 쉬움
- 무한 스크롤 구현 쉬움
- code link
Select Media / Create Story Screen
Profile Screen
실제로 해보니까...
- UI 관련 작업은 상당히 빠르고 쾌적하게 작업 가능
- 다시 컴파일 할 필요가 없이 빠르게 화면에 반영
- css flex 지식이 있다면
- 웹이랑 유사한 느낌
- 그러나 실제 시간을 많이 쓰는 부분은 Native 관련 오류
- 네이티브 코드 볼 줄 알아야 함
- 안드로이드는 문제가 생겼을 때 쉽게쉽게
해결 할 수 있었으나 iOS는 해결이 잘 안 되어서 포기(cocoapods 문제로 예상)
Tools
Code Push
- react-native의 js bundle만 원격으로 배포하여
각 앱스토어에 배포할 필요 없이 앱 업데이트를 가능하게 해줌 - http://microsoft.github.io/code-push/
Code Push Setup
// code push cli install
npm install -g code-push-cli
// register
// 브라우저가 열리며 계정을 연동하는 과정을 거침
// 계정 연동 후 발급된 토큰을 console에 붙여넣음
code-push register
// 앱 등록
// code-push app add <ProjectName> <Platform> react-native
code-push app add HelloRN android react-native
// 앱에 code-push 모듈 설치
npm install --save react-native-code-push@latest
react-native link react-native-code-push
Code Push
code-push release-react HelloRN android
Expo
- js bundle만 전송 받아서 렌더링 하는 앱
- 네이티브 영역은 숨겨져 있고, JS 코드만 드러나있음
- 네이티브 연동이 필요한 모듈은 연동하기 어려움
- 일부 네이티브 기능은 expo에서 자체적으로 지원
- 네이티브 기능이 필요 없거나 expo로 커버할 수 있다면 좋은 선택
create-react-native-app
- expo 기반
- 플랫폼 별 네이티브 코드들이 숨겨져 있음
- 네이티브 기능이 크게 중요하지 않다면 좋은 선택