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版:
- 傳統Native版:iOS和Android的App entry point分開,但App裡面可以共用Component,以及可以安裝各自平台的Native package(最重要的分別)
- CRNA版:只有一個
App.js
,基本上iOS和Android都是同一個App,不用處理平台間的分別,甚至不用安裝XCode或Android Studio,但一些有Native dependencies的library不能用。 - 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版。
建立各版本的初始專案
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:
- Expo XDE (一個mac/windows/linux的software)
- Command Line Tool:
exp
安裝教學
用XDE來新建Project
本人建議用XDE來日常開發,用exp來deploy、publish和build project。
Project Structure
與CRNA版本也是大同小異,要注意的是app.json
在這裡是很重要的。
Detach
日後如果真的需要加入native code的話,可以選擇detach。Detach後會出現ios
和android
的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:
- aws-amplify:Pure JS library,無法處理Push Notification
- aws-skd-js:同上
- aws-sdk-react-native:已日久失修,不知還能否用
Amazon SNS Mobile Push(不能用)
基本上是自己取得APN或FCM/GCM token,然後自己動手send到aws,全人手。。。
- Procedures: https://docs.aws.amazon.com/sns/latest/dg/mobile-push-pseudo.html
- Setup: https://docs.aws.amazon.com/sns/latest/dg/mobile-push-send.html
C. CRNA版本
CRNA App基本上不能做Push Notification,唯一出路就是變成其他版本。
- 使用Expo:Expo工具可以直接運行CRNA project
- Detach to ExpoKit:會變成native版本,但可以使用
ExpoKit
,提供Expo的Push Notification功能。 - Detach to bare React Native:變成native版本,可以直接用上述的各種libraries和services。
詳情請細閱這個issue。
Over-The-Air Update各版本做法
- Expo:依賴Expo的publish方法,可以分channel update
- Native版:使用非常著名、由Microsoft推出的CodePush
- CRNA:沒有辦法,要像上述一樣選一個方案
進化。