一、創(chuàng)建工程
到自己創(chuàng)建項(xiàng)目的文件夾下輸入命令:
react-native init 項(xiàng)目名
當(dāng)然如果你想指定安裝react-native版本的話你也可以這樣
后面的0.57.1可以自定義成自己的版本
react-native init 項(xiàng)目名 --version 0.57.1
目錄結(jié)構(gòu)還這樣的

這里android和ios 文件夾你可以刪掉換成自己的現(xiàn)有iOS和安卓項(xiàng)目.
刪掉android和iOS文件夾后
添加React Native所需要的依賴
目錄結(jié)構(gòu)如下
RN項(xiàng)目
├── Android項(xiàng)目
├── iOS項(xiàng)目
├── package.json
├── node_modules
└── .gitignore
我們來(lái)先說(shuō)安卓怎么配置
第一步:配置maven
接下來(lái)我們需要為已經(jīng)存在的RN項(xiàng)目添加 React Native依賴,在RN項(xiàng)目/Android項(xiàng)目/app/build.gradle文件中添加如下
dependencies {
compile 'com.android.support:appcompat-v7:+'
...
compile "com.facebook.react:react-native:+" // From node_modules
}

然后,我們?yōu)镽N項(xiàng)目配置使用的本地React Native maven目錄,在RN項(xiàng)目/Android項(xiàng)目/build.gradle文件中添加如下代碼:
allprojects {
repositories {
mavenLocal()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
...
}
...
}

這里需要注意的是
url "$rootDir/../node_modules/react-native/android"路徑的問(wèn)題如果你是把package.json文件放在Android項(xiàng)目目錄下的話
也就是說(shuō)RN項(xiàng)目/Android項(xiàng)目/package.json
那么這里你要這么寫(xiě)
提示:為確保你配置的目錄正確,可以通過(guò)在Android Studio中運(yùn)行Gradle sync 看是否有 “Failed to resolve: com.facebook.react:react-native:0.x.x” 的錯(cuò)誤出現(xiàn),沒(méi)有錯(cuò)誤則說(shuō)明配置正確,否則說(shuō)明配置路由有問(wèn)題。
url "$rootDir/node_modules/react-native/android
第二步:配置權(quán)限
接下來(lái)我們?yōu)锳PP運(yùn)行配置所需要的權(quán)限:檢查你項(xiàng)目中的AndroidManifest.xml文件中看是否有如下權(quán)限:
<uses-permission android:name="android.permission.INTERNET" />
另外,如果你需要用到RN的Dev Settings功能:

則需要在AndroidManifest.xml文件中添加如下代碼:
<activity android:name="com.facebook.react.devsupport.DevSettingsAc
第三步:指定要ndk需要兼容的架構(gòu)(重要)
Android不能同時(shí)加載多種架構(gòu)的so庫(kù),現(xiàn)在很多Android第三方sdks對(duì)abi的支持比較全,可能會(huì)包含armeabi, armeabi-v7a,x86, arm64-v8a,x86_64五種abi,如果不加限制直接引用會(huì)自動(dòng)編譯出支持5種abi的APK,而Android設(shè)備會(huì)從這些abi進(jìn)行中優(yōu)先選擇某一個(gè),比如:arm64-v8a,但如果其他sdk不支持這個(gè)架構(gòu)的abi的話就會(huì)出現(xiàn)crash。
在app/gradle 文件中添加如下代碼:
這地方也有個(gè)坑
NDK的架構(gòu)是有自己項(xiàng)目定義的,有些項(xiàng)目并沒(méi)有X86
所以這里一定要填寫(xiě)上,不然項(xiàng)目會(huì)直接崩潰 或者 模擬器無(wú)法啟動(dòng)RN 頁(yè)面
defaultConfig {
....?
ndk {
abiFilters "armeabi-v7a", "x86"
}
}
上面這些Android就簡(jiǎn)單的配置完成了
然后修改RN項(xiàng)目的index.js文件
如果你項(xiàng)目比較老的話,那么這個(gè)文件將是index.ios.js和index.android.js請(qǐng)自行選擇
有些同學(xué)不會(huì)導(dǎo)入包裹
import { AppRegistry } from 'react-native';
import App from './App';
AppRegistry.registerComponent('App1', () => App);
App1就是以后你要跳轉(zhuǎn)到的RN 項(xiàng)目的頁(yè)面
另外,在上述代碼中我們引用了一個(gè)App.js文件
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View
} from 'react-native';
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
我是RN頁(yè)面
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
}
});
為React Native創(chuàng)建一個(gè)Activity來(lái)作為容器
創(chuàng)建RNPageActivity
首先我們需要?jiǎng)?chuàng)建一個(gè)Activity來(lái)作為React Native的容器,
//有些同學(xué)不知道包名是什么這里我都直接導(dǎo)入復(fù)制進(jìn)來(lái)
import android.app.Activity;
import android.databinding.Bindable;
import android.os.Bundle;
import android.view.KeyEvent;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;
import com.lanto.goodfix.base.SimpleActivity;
public class RNPageActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
// 這個(gè)"App1"名字一定要和我們?cè)趇ndex.js中注冊(cè)的名字保持一致AppRegistry.registerComponent()
mReactRootView.startReactApplication(mReactInstanceManager, "App1", null);
setContentView(mReactRootView);
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
}
//為ReactInstanceManager添加Activity的生命周期回調(diào)
//一個(gè) ReactInstanceManager可以被多個(gè)activities或fragments共享,
//所以我們需要在Activity的//生命周期中回調(diào)ReactInstanceManager的對(duì)于的方法。
@Override
protected void onPause() {
super.onPause();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostPause(this);
}
}
@Override
protected void onResume() {
super.onResume();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostResume(this, this);
}
}
@Override
public void onBackPressed() {
if (mReactInstanceManager != null) {
mReactInstanceManager.onBackPressed();
} else {
super.onBackPressed();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostDestroy(this);
}
if (mReactRootView != null) {
mReactRootView.unmountReactApplication();
}
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (getUseDeveloperSupport()) {
if (keyCode == KeyEvent.KEYCODE_MENU) {//Ctrl + M 打開(kāi)RN開(kāi)發(fā)者菜單
mReactInstanceManager.showDevOptionsDialog();
return true;
}
}
return super.onKeyUp(keyCode, event);
}
參數(shù)說(shuō)明
setBundleAssetName:打包時(shí)放在assets目錄下的JS bundle包的名字,App release之后會(huì)從該目錄下加載JS bundle;
setJSMainModulePath:JS bundle中主入口的文件名,也就是我們上文中創(chuàng)建的那個(gè)index.js文件;
addPackage:向RN添加Native Moudle,在上述代碼中我們添加了new MainReactPackage()這個(gè)是必須的,另外,如果我們創(chuàng)建一些其他的Native Moudle也需要通過(guò)addPackage的方式將其注冊(cè)到RN中。需要指出的是RN除了這個(gè)方法外,也提供了一個(gè)addPackages方法用于批量向RN添加Native Moudle;
setUseDeveloperSupport:設(shè)置RN是否開(kāi)啟開(kāi)發(fā)者模式(debugging,reload,dev memu),比如我們常用開(kāi)發(fā)者彈框;
setInitialLifecycleState:通過(guò)這個(gè)方法來(lái)設(shè)置RN初始化時(shí)所處的生命周期狀態(tài),一般設(shè)置成LifecycleState.RESUMED就行,和下文講的Activity容器的生命周期狀態(tài)關(guān)聯(lián);
mReactRootView.startReactApplication:它的第一個(gè)參數(shù)是mReactInstanceManager,第二個(gè)參數(shù)是我們?cè)趇ndex.js中注冊(cè)的組件的名字,第三個(gè)參數(shù)接受一個(gè)Bundle來(lái)作為RN初始化時(shí)傳遞給JS的初始化數(shù)據(jù)
在中AndroidManifest.xml注冊(cè)一個(gè)RNPageActivity
<activity
android:name=".RNPageActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize"
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
運(yùn)行React Native
找到你package.json的所在文件夾輸入
npm start
然后我們打開(kāi)AndroidStudio,點(diǎn)擊運(yùn)行按鈕或者通過(guò)快捷鍵Ctrl+R來(lái)將項(xiàng)目安裝到模擬器上:

添加更多React Native的組件
import { AppRegistry } from 'react-native';
import App from './App';
import App2 from './App2';
AppRegistry.registerComponent('App1', () => App);
AppRegistry.registerComponent('App2', () => App);
//這里可以添加多個(gè),只要對(duì)應(yīng)就可以了
//目前這種方法是可以自定義比較靈活的一種集成方式
//祝大家好運(yùn),到此安卓就集成完成了
下面再說(shuō)幾句
如果你是在模擬器上運(yùn)行,那么這樣就可以了
如果是真機(jī),你要這樣輸入
先安裝index.android.bundle
//先創(chuàng)建下面路徑的assets文件夾
react-native bundle --platform android --dev false --entry-file index.js --bundle-output 安卓項(xiàng)目名/app/src/main/assets/index.android.bundle --assets-dest app/src/main/res/
//一定要注意你的路徑
//然后終端輸入
adb reverse tcp:8081 tcp:8081
npm start
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^分割線^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
下面就是iOS項(xiàng)目的集成了
iOS項(xiàng)目我們采用pod來(lái)集成,相對(duì)簡(jiǎn)單,不會(huì)出現(xiàn)各種添加錯(cuò)誤的問(wèn)題
首先在pod Podfile文件中添加
這里需要主語(yǔ)rn_path 路徑問(wèn)題,寫(xiě)你自己的路徑
rn_path = '../node_modules/react-native'
pod 'React', :path => '../node_modules/react-native', :subspecs => [
'Core',
'ART',
'CxxBridge',
'RCTActionSheet',
'RCTGeolocation',
'RCTImage',
'RCTAnimation’,
'RCTNetwork',
'RCTPushNotification',
'RCTSettings',
'RCTText',
'RCTVibration',
'RCTWebSocket',
'RCTLinkingIOS',
'DevSupport'
]
pod 'yoga', path: "#{rn_path}/ReactCommon/yoga"
pod 'glog', :podspec => "#{rn_path}/third-party-podspecs/glog.podspec"
#
# React Native third party dependencies podspecs
pod 'DoubleConversion', :podspec => "#{rn_path}/third-party-podspecs/DoubleConversion.podspec"
pod 'Folly', :podspec => "#{rn_path}/third-party-podspecs/Folly.podspec"
然后到podfile所在文件夾 再次
pod install
如果運(yùn)行起來(lái)后報(bào)這個(gè)錯(cuò)誤的話

請(qǐng)用以下解決
在podfile 文件中添加如下代碼
def change_lines_in_file(file_path, &change)
print "Fixing #{file_path}...\n"
contents = []
file = File.open(file_path, 'r')
file.each_line do | line |
contents << line
end
file.close
File.open(file_path, 'w') do |f|
f.puts(change.call(contents))
end
end
post_install do |installer|
# https://github.com/facebook/yoga/issues/711#issuecomment-381098373
change_lines_in_file('./Pods/Target Support Files/yoga/yoga-umbrella.h') do |lines|
lines.reject do | line |
[
'#import "Utils.h"',
'#import "YGLayout.h"',
'#import "YGNode.h"',
'#import "YGNodePrint.h"',
'#import "YGStyle.h"',
'#import "Yoga-internal.h"',
].include?(line.strip)
end
end
# https://github.com/facebook/yoga/issues/711#issuecomment-374605785
change_lines_in_file('../node_modules/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.h') do |lines|
unless lines[27].include?("#ifdef __cplusplus")
lines.insert(27, "#ifdef __cplusplus")
lines.insert(34, "#endif")
end
lines
end
# https://github.com/facebook/react-native/issues/13198
change_lines_in_file('../node_modules/react-native/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.h') do |lines|
lines.map { |line| line.include?("#import <RCTAnimation/RCTValueAnimatedNode.h>") ? '#import "RCTValueAnimatedNode.h"' : line }
end
# https://github.com/facebook/react-native/issues/16039
change_lines_in_file('../node_modules/react-native/Libraries/WebSocket/RCTReconnectingWebSocket.m') do |lines|
lines.map { |line| line.include?("#import <fishhook/fishhook.h>") ? '#import "fishhook.h"' : line }
end
end
接下來(lái)你需要配置index.js文件 這里就省略了 同安卓那邊的,可以自己看
也就是這步
import { AppRegistry } from 'react-native';
import App from './App';
import App2 from './App2';
AppRegistry.registerComponent('App1', () => App);
AppRegistry.registerComponent('App2', () => App);
接下來(lái)在你需要跳轉(zhuǎn)的地方OC代碼里加入
NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
RCTRootView *rootView =
[[RCTRootView alloc] initWithBundleURL: jsCodeLocation
moduleName: @"QiXiu"
initialProperties:
@{
@"name" : @[
@{
@"name" : @"Alex",
@"value": @"42"
},
@{
@"name" : @"Joel",
@"value": @"10"
}
]
}
launchOptions: nil];
UIViewController *vc = [[SHCustomerViewController alloc] init];
vc.view = rootView;
//[self presentViewController:vc animated:YES completion:nil];
[self.navigationController pushViewController:vc animated:nil];
vc.title = @"我是RN頁(yè)面";
注意這行代碼[[RCTRootView alloc] initWithBundleURL: jsCodeLocation moduleName: @"App1" initialProperties:
這里的 App1 就是你配置的頁(yè)面