移動開發中的React Native研究

關于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 NativeCordova應用的即時更新

使用非常簡單, 基于命令行

  • 發送更新
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-material-kit示例

react-native_03.gif

react-native-vector-icons

react-native-vector-icons的一句話介紹就是: 3000 Customizable Icons for React Native

react-native-app-intro

react-native-app-intro示例

react-native_04.gif

更多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

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

  • Mocha and Chai for UT

  • 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的缺點

  • 版本仍在迭代中
react-native_01.png
  • Learn Once, Write many times
react-native_02.png
  • 對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

參考

更多文章, 請支持我的個人博客

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • React Native優秀博客,以及優秀的Github庫列表(很多英文資料源自于[awesome-react-n...
    董董董董董董董董董大笨蛋閱讀 10,735評論 4 162
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,372評論 25 708
  • 原來喜歡, 會從心底偷偷跑出來在唇角漾成一朵花 原來喜歡, 會背叛不由衷的唇在眼里折射為一抹璀璨 原來喜歡, 會拆...
    如晤閱讀 235評論 0 1
  • 在review代碼或者解bug的經常會發現一些可以優化的地方,但是這些優化的幅度可能微乎其微,這時候要不要改就很糾...
    100斤閱讀 317評論 0 0
  • 寧靜陪你刷小能熊anki卡片,每日分享5個詞根,5個詞綴的記憶方法。 閑話 央視報道,昨天,新浪微博對19個低俗追...
    金色的寧靜閱讀 291評論 0 1