关于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
参考
更多文章, 请支持我的个人博客