移动开发中的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

参考

更多文章, 请支持我的个人博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • React Native优秀博客,以及优秀的Github库列表(很多英文资料源自于[awesome-react-n...
    董董董董董董董董董大笨蛋阅读 10,572评论 4 162
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,056评论 25 707
  • 原来喜欢, 会从心底偷偷跑出来在唇角漾成一朵花 原来喜欢, 会背叛不由衷的唇在眼里折射为一抹璀璨 原来喜欢, 会拆...
    如晤阅读 209评论 0 1
  • 在review代码或者解bug的经常会发现一些可以优化的地方,但是这些优化的幅度可能微乎其微,这时候要不要改就很纠...
    100斤阅读 294评论 0 0
  • 宁静陪你刷小能熊anki卡片,每日分享5个词根,5个词缀的记忆方法。 闲话 央视报道,昨天,新浪微博对19个低俗追...
    金色的宁静阅读 286评论 0 1