React Native如何集成到现有项目中

本系列文章作为学习RN期间的总结

虽然ReactNative能做到iOS和Android的大部分逻辑共享一套代码,节约开发成本;拥有像JSPatch那样的热修复功能,为线上问题提供非常灵活的解决方案。但是为什么大部分公司还是持观望态度,或者只在产品的某些部分用RN进行开发呢?

首先,React Native官方的某些组件仍然存在性能瓶颈,开发复杂场景的时候可能会遇到性能问题,像ListView,动不动就渲染整个视图,虽然推出了FlatList但是也存在着一些其他的Bug。其次,RN的周边生态并不完善,很多OC或Swift上已有的Library在NR上需要通过RN提供的方法重新用JS实现或者需要把这些库桥接到RN。因此大部分公司会选择交互不多,页面不太复杂的场景来尝试。本章,主要介绍如果在已有的App中集成React Native。

关键步骤

  1. 设置RN的依赖和目录结构
  2. 搞清楚你要在你的项目中使用的RN组件
  3. 使用CocoaPods添加你要使用的RN组件的依赖
  4. 使用npm安装JS组件
  5. 在JavaScript环境下,开发你的RN模块
  6. 添加一个RCTRootView到你的app。它将会作为容器展示你的RN模块。
  7. 启动RN服务,Run你的App。

前置条件:安装Node、npm最新版本(npm是基于Node实现的包管理工具和iOS的CocoaPod地位相当)

设置RN的依赖和目录结构

为React Native项目创建一个新的文件夹,在文件夹中新建/ios目录,拷贝所有原项目的内容到/ios目录下。

安装JavaScript依赖

在刚刚新建的文件夹中(即根目录中)创建一个package.json文件,并添加一下内容:

{
  "name": "Snapvote",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "react": "16.0.0-alpha.12",
    "react-native": "0.48.4",
    "react-native-vector-icons": "^4.4.2",
    "whatwg-fetch": "^2.0.3"
  },
  "devDependencies": {
    "babel-jest": "21.2.0",
    "babel-preset-react-native": "4.0.0",
    "jest": "21.2.0",
    "react-test-renderer": "16.0.0-alpha.12"
  },
  "jest": {
    "preset": "react-native"
  }
}

接下去,安装react和react-native包。打开Terminal,在你项目的根目录下面执行下面命令:

npm install --save r16.0.0-alpha.12 react-native

要确保这里安装的版本和package.json里说明的版本一致

执行这个命令之后,将会在项目的根目录下创建一个/node_modules的目录,这里保存着所有你项目中所需的JavaScript依赖。

安装CocoaPods

这里就不说了

配置CocoaPods依赖

在你集成RN到你项目中之前,你需要选择你要使用的React Native库。你将通过CocoaPod库的开发模式将其集成进去。

pod_develop

这些库的subspec文件都会在/node_modules目录下被说明,最后执行pod install命令,所有的React Native库依赖到这里就都准备好了。
pod_file

业务代码
  1. 创建 index.js 文件
    在项目的根目录下创建index.js文件,这个文件是你RN项目的
    入口,所有在Native中要用到的RN模块都在这里面进行注册。例如项目中的投票列表、设置页面等。各个模块的名称要和Native中的模块名称对应。

    rn_modul

  2. 添加React Native 代码(JavaScript和CSS)

'use strict';

import React from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  FlatList,
  NativeModules,
  Image,
  ActivityIndicator,
  TouchableOpacity,
  ScrollView,
  Switch,
  TouchableWithoutFeedback,
  Alert,
  NativeEventEmitter,
  
} from 'react-native';

import StarRatingView from './starRating.view.js'

var { width, height } = require('Dimensions').get('window');
var nativeModuleManager = NativeModules.XYRCTBrigeModule;

class SettingsView extends React.PureComponent{

    constructor(props){
        super(props);
    }
    .....
    .....

在Native中使用RCTRootView作为RN模块的容器。所有通过RN渲染出来的视图都会展示在该View上。

#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  NSURL *jsCodeLocation;
  {{< hl-text green >}}//设置获取JavaScript文件的路径,从服务器或者本地文件获取{{< /hl-text >}}
#if DEBUG
  jsCodeLocation = [NSURL URLWithString:@"http://10.0.30.119:8081/index.ios.bundle?platform=ios"];
#else
  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
#endif
  
  {{< hl-text green >}}//通过URL、模块名称加载对应的RN视图,生成一个OC对象`RCTRootView`,最后将该View添加到controller的View上{{< /hl-text >}}
  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"TabberView"
                                               initialProperties:nil
                                                   launchOptions:launchOptions];
  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
  
  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];
  return YES;
}

到这里就完成了一个简单React Native App的集成。

测试

  1. 因为HTTPS的限制,请将Domain添加到Info.plist的白名单
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>localhost</key>
        <dict>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>
  1. 执行npm start开启本地服务
  2. Xcode run.
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,057评论 25 707
  • 想了很久,要先介绍各种组件的实际应用好,还是先介绍怎么把React Native集成到原生项目好。因为想起,一旦开...
    朱_源浩阅读 22,722评论 84 129
  • React Native学习<一> 认识Recat Native 博客原文:http://www.jianshu....
    AFinalStone阅读 2,630评论 0 12
  • 每每跟人说起自己的孩子,总有人会回应说:"你不像是当妈的。" 我会沾沾自喜的把这个当作恭维的好话,安心放肚子里听着...
    孙大猫阅读 435评论 4 4
  • 被地瓜诱惑,导致断碳水受挫折。断碳水一个星期了。一点没有瘦,非常沮丧。当我把一整个地瓜吃下之后,非常有罪恶感,在没...
    狂奔的阿肥阅读 77评论 0 0