關于React Native詳細介紹和基本使用, 可以直接參考官方手冊, 本文就不重復造輪子了
目錄
集成和打包
重新創建純的React Native工程的教程和文章有很多, 在此就直接略過了
iOS
如何將React Native集成到Native的工程中, 官網也有介紹Integration With Existing Apps, 這里就不詳細解釋了
在打包時需要注意的是, 首先使用如下命令將React Native資源打成bundle
react-native bundle --entry-file index.ios.js --platform ios --bundle-output ios/react.bundle
然后打開Xcode, 將react.bundle添加至工程中, 最后和普通的iOS工程一樣, 打包發布即可
Demo的完整工程代碼, 參考這里的ReactNativeAndNativeDemo
android
和iOS類似, 打包android時, 首先也需要將React Native資源打成bundle
react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/ReactNativeAndNativeDemo/app/src/main/assets/index.android.bundle --assets-dest android/ReactNativeAndNativeDemo/app/src/main/res/
然后, 再打包發布
關于更多android打包, 可以參考React Native發布APP之簽名打包APK
數據持久化
AsyncStorage
import { AsyncStorage } from 'react-native';
var keyName = 'key';
var keyValue = '262';
AsyncStorage.setItem(keyName, keyValue, (error) => {
console.log('' + error);
});
AsyncStorage.getItem(keyName, (error, result) => {
console.log('' + result);
});
優點
react native自帶
簡單易用
缺點
- 只能存儲字符串
NSUserDefaults
// ReactViewBridgeModule.h
#import <Foundation/Foundation.h>
#import <RCTBridgeModule.h>
@interface ReactViewBridgeModule : NSObject <RCTBridgeModule>
@end
// ReactViewBridgeModule.m
#import "ReactViewBridgeModule.h"
@implementation ReactViewBridgeModule
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(setUserDefaults:(NSString *)key value:(NSString *)value) {
[[NSUserDefaults standardUserDefaults] setObject:value forKey:key];
}
RCT_EXPORT_METHOD(getUserDefaults:(NSString *)key callback:(RCTResponseSenderBlock)callback) {
NSString *ret = [[NSUserDefaults standardUserDefaults] objectForKey:key];
NSLog(@"ret = %@", ret);
if(!ret){
ret = @"";
}
callback(@[ret]);
}
@end
NativeModules.ReactViewBridgeModule.setUserDefaults(keyName, keyValue);
NativeModules.ReactViewBridgeModule.getUserDefaults(keyName, (value) => {
console.log(value);
});
優點
- 相比AsyncStorage支持更多的存儲數據類型
缺點
需要實現Native與Javascript的通信
依賴于iOS平臺
react-native-sqlite-storage
這里使用的是react-native-sqlite-storage, 你也可以在github上參考其他sqlite的實現, 其中詳細的安裝和配置, 仍然參考react-native-sqlite-storage
import SQLite from 'react-native-sqlite-storage';
// insert operation
var db = SQLite.openDatabase("test.db", "1.0", "Test Database", 200000,
() => {
console.log('opened');
var sql = 'CREATE TABLE IF NOT EXISTS UserTable (FirstName varchar(255), LastName varchar(255))';
db.transaction((tx) => {
tx.executeSql(sql, [], (tx, results) => {
console.log('' + results);
});
});
var insertsql = "INSERT INTO UserTable VALUES ('mu', 'ji')";
db.transaction((tx) => {
tx.executeSql(insertsql, [], (tx, results) => {
console.log('' + results);
});
});
},
(error) => {
console.log('open error: ' + error);
});
// query operation
var db = SQLite.openDatabase("test.db", "1.0", "Test Database", 200000,
() => {
console.log('opened');
var querysql = "SELECT * FROM UserTable";
db.transaction((tx) => {
tx.executeSql(querysql, [], (tx, results) => {
var len = results.rows.length;
for (let i = 0; i < len; i++) {
let row = results.rows.item(i);
console.log(`User name: ${row.FirstName}, Dept Name: ${row.LastName}`);
}
});
});
},
(error) => {
console.log('open error: ' + error);
});
Realm
關于Realm的更多介紹可以參考Realm
import Realm from 'realm';
let realm = new Realm({
schema: [{name: 'Dog', properties: {name: 'string'}}]
});
realm.write(() => {
realm.create('Dog', {name: 'Rex'});
});
<Text>Count of Dogs in Realm: {realm.objects('Dog').length}</Text>
安裝Realm時, 這條命令是一定要執行的: react-native link relam
熱補丁
CodePush
CodePush是由微軟出品, 支持React Native和Cordova應用的即時更新
使用非常簡單, 基于命令行
- 發送更新
code-push release <應用名稱> <Bundles所在目錄> <對應的應用版本> --deploymentName: 更新環境
--description: 更新描述 --mandatory: 是否強制更新
code-push release GitHubPopular ./bundles/index.android.bundle 1.0.6 --deploymentName Production --description "1.支持文章緩存。" --mandatory true
- 同步更新
import codePush from 'react-native-code-push'
codePush.sync()
如果可以進行更新, CodePush會在后臺靜默地將更新下載到本地, 等待APP下一次啟動的時候應用更新, 以確保用戶看到的是最新版本
如果更新是強制性的, 更新文件下載好之后會立即進行更新
但是CodePush也存在如下問題
服務器在國外, 在國內訪問, 網速不是很理想
其升級服務器端程序并不開源的, 后期微軟會不會對其收費還是個未知數
不支持增量更新
關于更多CodePush, 可以參考React Native熱更新部署/熱更新-CodePush最新集成總結
AppHub
AppHub由國外一家公司出品, 支持React Native應用的即時更新
它是免費服務有如下限制
1000個用戶
50MB的文件大小
除此之外AppHub的最大問題是對Swift和Android支持的情況并不好, 詳見Will an Android Library be implemented soon?
Siphon
Siphon也是支持React Native應用的即時更新, BUT
Siphon is shutting down on 27th July 2016.
To our customers, users and supporters: unfortunately this is the end of the road for Siphon. Our long-term goal was to create the most developer friendly end-to-end publishing platform for mobile apps.
Due to some inherent limitations in the early design decisions that we made (in particular the inability to compile your own native modules with Siphon) we have come to the regrettable conclusion that this vision is not possible at this time. We hoped that these native bridged modules would mature and become less important over time, but this has turned out to not be the case.
All apps created using Siphon are fully compatible with the standard React Native framework and transferring your app should only take a few minutes. Please email us if you need any help migrating your app.
Thanks to everyone who supported us over the past few months.
關于更多熱補丁方案的比較, 可以參考CodePush vs. Siphon vs. AppHub
第三方庫
Redux
Redux是什么?
Redux is a predictable state container for JavaScript apps
簡單來說, Redux是
狀態容器, 提供可預測化的狀態管理. 可以跟大部分的View層框架配合使用不限于 React
那么React Native中的state又是什么呢?
在React中, 把所有的component看做有窮狀態機, component由一個個的state來支撐, 有了不同的state, 即可重新渲染界面
Redux是Facebook官方針對React應用建議的架構, 想要了解Redux
Redux的三個要點
應用中所有state以對象樹形式存儲在一個store中
唯一改變state的方法是action
通過action觸發reducers來改變state樹
Redux的三個原則
單一數據源
state只讀
純函數執行修改
Redux的三個組成
store - 即state的容器, 在Redux中, 只有一個store
action - 是一個對象, 并且約定好type字段為字符串, 用于表示action類型, 例如添加用戶的action
{
type: 'ADD_USER',
data: {
name: 'username',
email: 'username@domain.com',
psw: '123456'
}
}
- reducer - action通過reducer來完成state的改變, reducer在store中來分發處理action
react-native-material-kit
react-native-vector-icons
react-native-vector-icons的一句話介紹就是: 3000 Customizable Icons for React Native
react-native-app-intro
更多UI組件, 可以參考JS.COACH
開源應用
f8app
f8app是Facebook官方出品的
We've created a series of tutorials at makeitopen.com that explain how we built the app, and that dive into how we used React Native, Redux, Relay, GraphQL, and more.
react-native-nba-app
react-native-nba-app Info
Platform: iOS & Android
State Management: Redux
Code Style: Standard
Unit Test: None, take a look at snowflake for learning
Related Articles: Let’s drawing charts in React-Native without any library
react-weather
react-weather Development stack
Flow was enabled to catch typing errors in React Native JavaScript code
Realm for React Native is used to persist data
I used Nuclide and Visual Studio Code on OSX, both have great support for React Native app development
I used git for version control, and stored progress on GitHub.
Currently only tested on an iOS device
reading
reading Application Architecture
Microsoft Code Push for dynamic update
Redux is a predictable state container for reading application, together with React Native
Redux-Saga is a library that aims to make side effects in reading application easier and better
Enzyme for testing React Native UI components and mock
Eslint is a tool for identifying and reporting on patterns found in reading application code
更多應用可以參考學習React Native必看的幾個開源項目(第一波)
總結
React Native的優勢
Based on JavaScript and React
Learn Once, Write Anywhere
React Native的缺點
- 版本仍在迭代中
- Learn Once, Write many times
- 對iOS的支持更早更好, 而android中的坑較多
React Native的比較
大廠都是基于Hybrid: 釘釘, 微信, QQ音樂, 淘寶, 京東...
使用React Native的大廠有攜程...(其他暫時沒找到了)
React Native與Hybrid開發都需要
- 終端工程師需要有一定的web經驗
React Native相比Hybrid的用戶體驗更好, 但是Hybrid在以下場景更有優勢
- 應用嚴重依賴網絡并且對更新延時敏感
對于React Native的更多探討, 可以參考Hybrid App 和 React Native 開發那點事, 我對 React Native 的理解和看法, 一個“三端”開發者眼中的React Native, React Native vs Ionic: A Side-by-Side Comparison
參考
更多文章, 請支持我的個人博客