React Native教學 Part 1 - 詳盡新手入門

2018/03/28 posted in  React Native comments

React Native近年相當熱門,很多人說可以取代傳統寫App的方法。以下是安裝和開始使用的新手入門、以及需要知道細節、工具的選擇等等。知道多一點,免得大家走上不歸路

甚麼是React Native?

簡而言之,React Native就是一個讓你可以用javascript開發native apps的library。

2013年,Facebook開源自己內部開發的React - 一個用javascript開發前端UI的架構。

2015年,Facebook推出React Native,同樣基於React的架構,分別在於render出來的不是DOM,而家iOS或Android的native elements。

優點

  • 真正Native:React Native的所有基礎Components都分別是原生iOS和Android的,提供與Native apps接近的體驗
    • 不同於Ionic等以HTML render的frameworks
  • 以JS控制App logics
  • Data-driven:來自React的feature
    • 一般基於Swift和Java的Native apps都是imperative地設置例如一個按鈕的properties
    • 而React component則是以passing props的方法,只要props有變,component就會自動適應而作出改變

三種版本

React Native分為傳統的Native版、CRNA (Create React Native App)版和Expo版:

  1. 傳統Native版:iOS和Android的App entry point分開,但App裡面可以共用Component,以及可以安裝各自平台的Native package(最重要的分別)
  2. CRNA版:只有一個App.js,基本上iOS和Android都是同一個App,不用處理平台間的分別,甚至不用安裝XCode或Android Studio但一些有Native dependencies的library不能用
  3. Expo版:不屬於官方版本,但本人推薦使用,以下會詳述。

建立CRNA project後如果想轉回Native版,也可以eject你的project,eject後build process會比較複雜,詳情可看這裡

選擇版本

先簡單講一開始怎樣選擇版本,詳細的決定還是要自己試一次才知道。

  • 如果你只是體驗一下React Native、在Sample Project裡隨便玩玩,請選擇CRNA版
  • 如果你要快速開發跨平台App、不需要太多Native功能如Background Location、不需要用react-native link的3rd-party libraries、不需要改xcode或android的project setting,請用Expo版
  • 如果你需要用到以上功能,請用傳統Native版

建立各版本的初始專案

(請先安裝Node.js)

I. 傳統Native版

安裝與運行

各平台安裝步驟不同,請按官方指示做。

react-native init ProjectName
react-native run-ios
react-native run-android

Project Structure

.
├── App.js  # App root component,所有JS code由這裡開始
├── android/  # Android native project
├── app.json  # React Native app config
├── index.js  # App entry point
├── ios/  # iOS native project
├── node_modules/  # JS libraries
├── package.json  # JS dependencies
└── yarn.lock
運作Logic

ios/android/裡的native project裡會調用react native去獲得Root Component,default就是指向index.js

打開index.js可以看到:

import { AppRegistry } from 'react-native';
import App from './App';  // import了App.js

AppRegistry.registerComponent('ReactNativeSampleProject', () => App);

App.js

// ...
export default class App extends Component<Props> {
    // ...
}
// ...

所以App.js就成為了你的Root Component,之後可以在這個App裡面加入你的JS Component,慢慢擴展你的App。

II. CRNA版

安裝與運行

官方指示安裝。

create-react-native-app AwesomeProject

cd AwesomeProject
npm start

Project Structure

.
├── App.js
├── App.test.js  # 基於Jest的test
├── README.md
├── app.json
├── node_modules
├── package.json
└── yarn.lock
與Native版本的分別

與Native版本最大分別就是沒有ios/android/兩個Native projects,取而代之,node_modules/expo會直接使用App.js作為你的Root Component

運作Logic

看一看package.json

"scripts": {
    "start": "react-native-scripts start",  // == npm start
    "eject": "react-native-scripts eject",
    "android": "react-native-scripts android",
    "ios": "react-native-scripts ios",
    "test": "jest"
  },
"dependencies": {
    "expo": "^26.0.0",  // expo
    "react": "16.3.0-alpha.1",
    "react-native": "0.54.0"
  }

執行npm start時會用上react-native-scripts,其實就是一個便利的工具去調用node_modules/expo去執行你的App。

(有興趣可以看看node_modules/expo/AppEntry.js
(所以說到底其實整個CRNA版本都是依賴Expo運作

III. 真正cross-platform react-native - Expo

Expo是一個幫助你開發React Native project的package,非常推薦使用。

為甚麼要用Expo?

  • Dev: 完全不需要處理Native的東西,可以專注寫Javascript。
  • Library: Expo提供一堆API讓你access到native的module,例如Camera、Contact、FileSystem等等。
  • Test Running: 提供Expo client app,可在iOS或Android device即時執行、傳送Debug messages、Hot Reload等等。
  • Release: Expo的Server會分別用幫你build .ipa.apk檔,不用開XCode或Android Studio。
  • Update: 透過Expo,User打開App時可以自動 OTA(Over-The-Air) Update 你的App到最新版本。

缺點

雖然Expo很方便,但也有一些缺點要留意:

  • 有時Expo提供的功能會有bug
  • 新版本推出得很快,而舊版本也deprecate得很快
  • Build standalone (.ipa/.apk)需要經Expo,但有時會有bug,尤其新版本剛推出的一兩個星期
  • Standalone的size有點大,最小約20-30MB

安裝與運行

Expo有兩種方法建立project:

  1. Expo XDE (一個mac/windows/linux的software)
  2. Command Line Tool: exp

安裝教學
用XDE來新建Project
本人建議用XDE來日常開發,用exp來deploy、publish和build project。

Project Structure

與CRNA版本也是大同小異,要注意的是app.json在這裡是很重要的。

Detach

日後如果真的需要加入native code的話,可以選擇detach。Detach後會出現iosandroid的Native project,你可以fully customize它們,裡面default會使用Expo的方法來運行你的App.js

其他資訊

以下是我的研究結果和經驗之談。知道多一點,比較多一點,可以令你更容易做對的決定。

Push Notification各版本做法

A. Expo版本

1. Expo本身的Push Notification功能
  • Apple Push Certificate: 在經過Expo server build project的時候,他們會幫你處理Push Certificate
  • Register token: 要在自己server儲存Expo Token
  • Send: Send request to Expo server with tokens
2. Firebase Cloud Messaging (new in v26.0.0)

https://docs.expo.io/versions/v26.0.0/guides/using-fcm

B. Native版本

可以使用各種現有Native工具,而一般大公司多數已經推出react native版本的工具。

1. OneSignal

https://github.com/geektimecoil/react-native-onesignal

2. Firebase

https://github.com/invertase/react-native-firebase
https://rnfirebase.io/docs/v3.1.x/messaging/reference/messaging

3. AWS
AWS Mobile Client

你的user開啟app時,用AWS Mobile Client register他們到aws,然後可以叫aws send notification給這些users。

https://docs.aws.amazon.com/aws-mobile/latest/developerguide/getting-started.html

React Native SDK(不能用)

我找到三個sdk:

  1. aws-amplify:Pure JS library,無法處理Push Notification
  2. aws-skd-js:同上
  3. aws-sdk-react-native:已日久失修,不知還能否用
Amazon SNS Mobile Push(不能用)

基本上是自己取得APN或FCM/GCM token,然後自己動手send到aws,全人手。。。

C. CRNA版本

CRNA App基本上不能做Push Notification,唯一出路就是變成其他版本。

  1. 使用Expo:Expo工具可以直接運行CRNA project
  2. Detach to ExpoKit:會變成native版本,但可以使用ExpoKit,提供Expo的Push Notification功能。
  3. Detach to bare React Native:變成native版本,可以直接用上述的各種libraries和services。

詳情請細閱這個issue

Over-The-Air Update各版本做法

  • Expo:依賴Expo的publish方法,可以分channel update
  • Native版:使用非常著名、由Microsoft推出的CodePush
  • CRNA:沒有辦法,要像上述一樣選一個方案進化

下一篇:React Native教學 Part 2 - Project Structure