React Native如何集成到現(xiàn)有項(xiàng)目中

本系列文章作為學(xué)習(xí)RN期間的總結(jié)

雖然ReactNative能做到iOS和Android的大部分邏輯共享一套代碼,節(jié)約開發(fā)成本;擁有像JSPatch那樣的熱修復(fù)功能,為線上問題提供非常靈活的解決方案。但是為什么大部分公司還是持觀望態(tài)度,或者只在產(chǎn)品的某些部分用RN進(jìn)行開發(fā)呢?

首先,React Native官方的某些組件仍然存在性能瓶頸,開發(fā)復(fù)雜場(chǎng)景的時(shí)候可能會(huì)遇到性能問題,像ListView,動(dòng)不動(dòng)就渲染整個(gè)視圖,雖然推出了FlatList但是也存在著一些其他的Bug。其次,RN的周邊生態(tài)并不完善,很多OC或Swift上已有的Library在NR上需要通過RN提供的方法重新用JS實(shí)現(xiàn)或者需要把這些庫(kù)橋接到RN。因此大部分公司會(huì)選擇交互不多,頁(yè)面不太復(fù)雜的場(chǎng)景來(lái)嘗試。本章,主要介紹如果在已有的App中集成React Native。

關(guān)鍵步驟

  1. 設(shè)置RN的依賴和目錄結(jié)構(gòu)
  2. 搞清楚你要在你的項(xiàng)目中使用的RN組件
  3. 使用CocoaPods添加你要使用的RN組件的依賴
  4. 使用npm安裝JS組件
  5. 在JavaScript環(huán)境下,開發(fā)你的RN模塊
  6. 添加一個(gè)RCTRootView到你的app。它將會(huì)作為容器展示你的RN模塊。
  7. 啟動(dòng)RN服務(wù),Run你的App。

前置條件:安裝Node、npm最新版本(npm是基于Node實(shí)現(xiàn)的包管理工具和iOS的CocoaPod地位相當(dāng))

設(shè)置RN的依賴和目錄結(jié)構(gòu)

為React Native項(xiàng)目創(chuàng)建一個(gè)新的文件夾,在文件夾中新建/ios目錄,拷貝所有原項(xiàng)目的內(nèi)容到/ios目錄下。

安裝JavaScript依賴

在剛剛新建的文件夾中(即根目錄中)創(chuàng)建一個(gè)package.json文件,并添加一下內(nèi)容:

{
  "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,在你項(xiàng)目的根目錄下面執(zhí)行下面命令:

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

要確保這里安裝的版本和package.json里說明的版本一致

執(zhí)行這個(gè)命令之后,將會(huì)在項(xiàng)目的根目錄下創(chuàng)建一個(gè)/node_modules的目錄,這里保存著所有你項(xiàng)目中所需的JavaScript依賴。

安裝CocoaPods

這里就不說了

配置CocoaPods依賴

在你集成RN到你項(xiàng)目中之前,你需要選擇你要使用的React Native庫(kù)。你將通過CocoaPod庫(kù)的開發(fā)模式將其集成進(jìn)去。

pod_develop

這些庫(kù)的subspec文件都會(huì)在/node_modules目錄下被說明,最后執(zhí)行pod install命令,所有的React Native庫(kù)依賴到這里就都準(zhǔn)備好了。
pod_file

業(yè)務(wù)代碼
  1. 創(chuàng)建 index.js 文件
    在項(xiàng)目的根目錄下創(chuàng)建index.js文件,這個(gè)文件是你RN項(xiàng)目的
    入口,所有在Native中要用到的RN模塊都在這里面進(jìn)行注冊(cè)。例如項(xiàng)目中的投票列表、設(shè)置頁(yè)面等。各個(gè)模塊的名稱要和Native中的模塊名稱對(duì)應(yīng)。

    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渲染出來(lái)的視圖都會(huì)展示在該View上。

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

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  NSURL *jsCodeLocation;
  {{< hl-text green >}}//設(shè)置獲取JavaScript文件的路徑,從服務(wù)器或者本地文件獲取{{< /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、模塊名稱加載對(duì)應(yīng)的RN視圖,生成一個(gè)OC對(duì)象`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;
}

到這里就完成了一個(gè)簡(jiǎn)單React Native App的集成。

測(cè)試

  1. 因?yàn)镠TTPS的限制,請(qǐng)將Domain添加到Info.plist的白名單
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>localhost</key>
        <dict>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>
  1. 執(zhí)行npm start開啟本地服務(wù)
  2. Xcode run.
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,733評(píng)論 25 709
  • 想了很久,要先介紹各種組件的實(shí)際應(yīng)用好,還是先介紹怎么把React Native集成到原生項(xiàng)目好。因?yàn)橄肫?,一旦開...
    朱_源浩閱讀 23,044評(píng)論 84 129
  • React Native學(xué)習(xí)<一> 認(rèn)識(shí)Recat Native 博客原文:http://www.jianshu....
    AFinalStone閱讀 2,814評(píng)論 0 12
  • 每每跟人說起自己的孩子,總有人會(huì)回應(yīng)說:"你不像是當(dāng)媽的。" 我會(huì)沾沾自喜的把這個(gè)當(dāng)作恭維的好話,安心放肚子里聽著...
    孫大貓閱讀 498評(píng)論 4 4
  • 被地瓜誘惑,導(dǎo)致斷碳水受挫折。斷碳水一個(gè)星期了。一點(diǎn)沒有瘦,非常沮喪。當(dāng)我把一整個(gè)地瓜吃下之后,非常有罪惡感,在沒...
    狂奔的阿肥閱讀 102評(píng)論 0 0

友情鏈接更多精彩內(nèi)容