React Native整合到現有的原生專案
因為專案需求,在iOS原生專案中會巢狀幾個RN介面,這就牽涉到了原生程式碼中巢狀RN程式碼的問題,至於整合步驟以及過程中遇到的坑都在下面一一列舉,以幫助後來人。
前提
RN環境已經搭建完成,如若未完成,請移步
React Native環境搭建
將React Native整合到iOS應用中主要有如下幾個步驟:
- 配置好React Native依賴和專案結構
- 瞭解你要整合的React Native元件
- 使用CocoaPods把這些元件以依賴的形式加入到專案中
- 建立js檔案,編寫React Native元件的js程式碼
- 在應用中新增一個
RCTRootView
,這個RCTRootView
正是用來承載你的React Native元件的容器- 啟動React Native的Packager服務,執行應用
- 驗證這部分元件是否正常工作
1. 配置專案目錄結構
我在此也是為了更加深入的瞭解RN,所以在這裡拿以前的小demo來做示範了。
首先建立一個空目錄用於存放React Native專案,然後在這個空目錄中建立一個ios
子目錄,把現有的iOS專案拷貝到ios
子目錄中
2. 安裝JavaScript依賴包
在專案根目錄下建立一個名為package.json
的檔案,其中填入以下內容:
{
"name": "MyReactNativeApp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start"
}
}
接下來使用yarn
或者npm
(兩者都是node的包管理器)來安裝React和React Native模組。
開啟終端,進入到根目錄中(即package.json)檔案所在目錄,然後執行以下命令安裝:
yarn add react-native
這樣預設安裝最新版本的React Native,命令執行完畢後可以看到輸出中有兩個警告資訊:
warning " > react-native@0.57.4" has unmet peer dependency "react@16.6.0-alpha.8af6728".
warning Your current version of Yarn is out of date. The latest version is "1.12.3", while you're on "1.9.4".
第一個警告提示還要安裝指定版本的React,第二個警告說是yarn版本不是最新的
然後執行命令安裝指定版本的React
yarn add react@16.6.0-alpha.8af6728
注意:必須嚴格匹配警告資訊中所列出的版本,高了或者低了都是不可以嘀!
完成這個步驟之後可以發現我們的根目錄下多了一些東西:
專案根目錄下的node_modules
目錄中安裝的都是JavaScript的以來模組(對於這個目錄,我們的原則是不復制、不移動、不修改、不上傳、隨用隨裝)
把node_modules/
目錄記錄到.gitignore
檔案中(即不上傳到版本控制系統,只保留到本地)
3. 安裝CocoaPods
CocoaPods是針對iOS和Mac開發的包管理工具。執行一下命令安裝CocoaPods
brew install cocoapods
安裝就不用過多的說了(畢竟都安裝的有)
4. 配置CocoaPods依賴
React Native框架整體是作為node模組安裝到專案中的。接下來我們就要在CocoaPods的Podfile中指定我們需要使用的subspecs
。
可用的subspecs
都列在node_modules/react-native/React.podspec
檔案中,基本上都是按照其功能命名的。一般來說第一個要新增的就是Core
,其包含了必須的AppRegistry
、StyleSheet
、View
以及其他的一些React Native核心庫。如果要使用React Native的Text
庫(即<Text>
元件),那就需要新增TCTText
的subspec
,等等。
我們需要在Podfile
檔案中指定所需要的subspec
。建立Podfile
的最簡單方法就是在/ios
目錄中使用CocoaPods的init
命令(如果原先專案中已經建立了Podfile
檔案,可以跳過此步):
pod init
這樣Podfile
就已經建立了,接下來就需要調整其內容以滿足整合需求,調整後的Podfile
內容類似下面的:
# target的名字一般與你的專案名字相同
target 'NumberTileGame' do
# 'node_modules'目錄一般位於根目錄中
# 但是如果你的結構不同,那你就要根據實際路徑修改下面的`:path`
pod 'React', :path => '../node_modules/react-native', :subspecs => [
'Core',
'CxxBridge', # 如果RN版本 >= 0.47則加入此行
'DevSupport', # 如果RN版本 >= 0.43,則需要加入此行才能開啟開發者選單
'RCTText',
'RCTNetwork',
'RCTWebSocket', # 除錯功能需要此模組
'RCTAnimation', # FlatList和原生動畫功能需要此模組
# 在這裡繼續新增你所需要的其他RN模組
]
# 如果你的RN版本 >= 0.42.0,則加入下面這行
pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
# 如果RN版本 >= 0.45則加入下面三個第三方編譯依賴
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
end
修改好Podfile
檔案後,就可以開始安裝React Native的pod包了:
pod install
5. RN程式碼整合
依賴搞好之後,就可以愉快的搞程式碼咯,接下來我們在根目錄中建立一個名為home.js
的檔案(個人建議功能檔案單獨建立資料夾放到一塊,不要都擠在根目錄中),實現以下內容(這裡的內容可以隨便咯):
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, NativeModules, NativeAppEventEmitter} from 'react-native';
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
android:
'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});
var rn = NativeModules.HmRNViewController;
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native!</Text>
<Text style={styles.instructions}>Hello World</Text>
<Text style={styles.instructions}>這裡是RN介面</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
程式碼碼好了,接下來就是要iOS原生應用能夠呼叫的到的這個頁面,我們需要在專案根目錄下建立一個空的index.js
檔案(入口檔案建議放在根目錄下)
index.js
檔案是React Native應用在iOS上的入口檔案,該入口檔案也可以像iOS的main
入口檔案一樣簡單,在其中實現以下內容即可完成:
import {AppRegistry} from 'react-native';
import home from './home.js'; // 引入當前目錄下的home.js檔案
// 註冊元件
AppRegistry.registerComponent('homePage', () => home);
6. iOS程式碼整合
RN程式碼搞定,接下來就是在iOS原生專案中對接RN了,這也是重點:
假設當前的原生專案中A介面有一個按鈕,點選之後要讓跳轉到RN介面,主要實現如下:
在iOS專案中新建一個ViewController
介面B,在B介面的viewDidLoad
方法中實現以下程式碼:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.title = @"B";
NSURL *jsCodeLocation;
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"homePage" initialProperties:@{@"name" : @"Max", @"value" : @"123456"} launchOptions:nil];
// 這裡如果引入的是一個頁面,可以使用self.view = rootView;,也可以使用[self.view addSubview:rootView];,不過使用addSubview:方法必須要給rootView設定frame
//如果是一個元件(如按鈕、輪播圖等等),則可以直接使用[self.view addSubview:rootView];將元件新增到當前view,並設定frame值:rootView.frame = CGRectMake(0, 100, 100, 100);
self.view = rootView;
}
A介面的按鈕點選事件中實現的功能就是普通的跳轉到B介面,這裡就略去了
7. 執行專案
執行專案,點選A介面的按鈕,即可跳轉到RN介面:
別慌別慌,要穩住,不就是一個紅屏嘛 哈哈哈
出現這個紅屏報錯的原因在於:有沒有發現執行專案少了點什麼?一般情況下,RN專案執行的時候都會自動啟動packager服務的,但是這裡沒有自動啟動,至於怎麼設定自動啟動packager服務我暫時也不知道,但是可以手動啟動的:
開啟終端,到達專案根目錄下(即package.json
所在目錄),然後執行命令:
npm start
然後終端形如:
剛剛開啟的終端就用於啟動packager服務了,想要執行專案要麼再開啟一個終端至根目錄下執行react-native run-ios
,要麼進入ios
資料夾開啟Xcode執行,執行結果如下:
在RN介面如果不想要原生的導航欄,可以在B介面中隱藏導航欄,總之,隨便搞起來吧
這篇文章所介紹的主要是更改目錄結構,環境配置等等,具體程式碼部分很有限,所以原始碼就不貼出來了。在後面還會陸續的貼出來我在學習RN中遇到的問題我和經驗分享。
相關文章
- React Native整合到原生專案示例React Native
- 7) React Native 整合到原生專案(iOS)React NativeiOS
- 整合 React Native 到現有的 Android 專案( Mac, Windows 通用版 )React NativeAndroidMacWindows
- iOS原生專案整合 React Native 一 導航iOSReact Native
- 原生專案如何從零開始整合 React NativeReact Native
- React Native在Android當中實踐(三)——整合到Android專案當中React NativeAndroid
- React-Native專案總結React
- react native 指定版本建立專案React Native
- React Native --踩坑記 之 建立指定 React Native版本的專案React Native
- Disruptor 實踐:整合到現有的爬蟲框架爬蟲框架
- 在 React Native 中原生實現動態匯入React Native
- react native社群專案知識點React Native
- react-native 修改專案名稱React
- 如何在 React Native 專案中使用 MQTTReact NativeMQQT
- React-native專案入門與思考React
- 分享 50 個完整的 React Native 專案React Native
- react-native專案結構介紹React
- (零) React Native 專案開發拾遺React Native
- Flutter入門進階之旅(十八)Flutter專案打包成aar整合到原生Android專案FlutterAndroid
- RN學習(四)——RN專案整合到現有iOS專案中iOS
- 使 React Native App 更具原生質感React NativeAPP
- 如何在現有的Vue專案中嵌入 Blazor專案?VueBlazor
- 建立一個react-native專案(2/4)React
- React Native專案自動化打包釋出React Native
- React Native 專案(One 【一個】客戶端)React Native客戶端
- react-native大型專案開發實踐React
- Flutter - 將 Flutter 整合到現有專案(iOS - Framework篇)FlutteriOSFramework
- 利用TypeScript構建優雅的React Native專案TypeScriptReact Native
- React-Native入門(1)-專案工程初識React
- React Native安卓專案打包釋出APK步驟React Native安卓APK
- React Native學習指南:React Native嵌入到原生應用的一次嘗試React Native
- React Native 原生模組封裝:支付寶示例React Native封裝
- React native 與Android原生互動方式(一)React NativeAndroid
- React-native 橋接Android原生開發React橋接Android
- 【3月更新】React Native 優秀開源專案大全React Native
- 微軟推出針對Windows的React Native開發專案微軟WindowsReact Native
- 學習React Native必看的幾個開源專案React Native
- React Native Expo開發的OW移動端專案React Native