与现有应用集成
React Native 非常适合从头开始开发新的移动应用。然而,它同样适合向现有的原生应用添加单一视图或用户流程。通过几个步骤,你可以添加基于 React Native 的新功能、屏幕、视图等。
具体步骤取决于你所针对的平台。
- Android(Java 和 Kotlin)
- iOS(Objective-C 和 Swift)
关键概念
将 React Native 组件集成到您的 Android 应用中的关键是:
- 设置正确的目录结构。
- 安装必要的 NPM 依赖。
- 将 React Native 添加到您的 Gradle 配置中。
- 编写第一个 React Native 界面的 TypeScript 代码。
- 通过 ReactActivity 将 React Native 与您的 Android 代码集成。
- 运行打包器测试集成,并查看应用运行效果。
使用社区模板
在您按照本指南操作时,建议参考 React Native 社区模板。该模板包含一个最小化的 Android 应用,有助于您理解如何将 React Native 集成到现有的 Android 应用中。
前置条件
请参照 设置开发环境 和 无框架使用 React Native 入门 指南,配置您的开发环境以构建适用于 Android 的 React Native 应用。
本指南假设您已经熟悉 Android 开发的基础知识,比如创建 Activities 和编辑 AndroidManifest.xml 文件。
1. 设置目录结构
为了确保顺畅体验,创建一个新的文件夹用于您的集成 React Native 项目,然后将现有的 Android 项目移动到 /android 子文件夹中。
2. 安装 NPM 依赖
进入根目录,运行以下命令:
curl -O https://raw.githubusercontent.com/react-native-community/template/refs/heads/0.83-stable/template/package.json
这将从社区模板复制 package.json 文件到您的项目中。
接着,运行以下命令安装 NPM 包:
- npm
- Yarn
npm install
yarn install
安装过程会创建一个新的 node_modules 文件夹。该文件夹存储所有构建项目所需的 JavaScript 依赖。
请在 .gitignore 文件中添加 node_modules/(这里有一份社区默认示例)。
3. 将 React Native 添加到您的应用中
配置 Gradle
React Native 使用 React Native Gradle 插件来配置依赖项和项目设置。
首先,编辑您的 settings.gradle 文件,添加以下内容(参考社区模板):
// 配置 React Native Gradle 设置插件以支持自动链接
pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }
plugins { id("com.facebook.react.settings") }
extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
// 如果使用 .gradle.kts 文件:
// extensions.configure<com.facebook.react.ReactSettingsExtension> { autolinkLibrariesFromCommand() }
includeBuild("../node_modules/@react-native/gradle-plugin")
// 在此包含您现有的 Gradle 模块。
// include(":app")
然后打开您的顶层 build.gradle 文件,添加以下行(参考社区模板):
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
+ classpath("com.facebook.react:react-native-gradle-plugin")
}
}
这确保了 React Native Gradle 插件 (RNGP) 在项目中可用。
最后,在应用模块的 build.gradle 文件中添加以下配置(应用模块的 build.gradle 通常在 app 文件夹中,参考社区模板文件):
apply plugin: "com.android.application"
+apply plugin: "com.facebook.react"
repositories {
mavenCentral()
}
dependencies {
// 其他依赖项
+ // 注意:这里故意不指定版本号,RNGP 会自动处理。
+ // 如果不使用 RNGP,需要手动指定版本。
+ implementation("com.facebook.react:react-android")
+ implementation("com.facebook.react:hermes-android")
}
+react {
+ // 需要启用自动链接 - https://github.com/react-native-community/cli/blob/master/docs/autolinking.md
+ autolinkLibrariesWithApp()
+}
最后,打开应用的 gradle.properties 文件,添加以下内容(参考社区模板):
+reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
+newArchEnabled=true
+hermesEnabled=true
配置清单文件
首先,确保您的 AndroidManifest.xml 文件中有 Internet 权限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".MainApplication">
</application>
</manifest>
然后,在debug 版本的 AndroidManifest.xml 中启用明文流量:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
+ android:usesCleartextTraffic="true"
+ tools:targetApi="28"
/>
</manifest>
这里是社区模板中用于参考的 AndroidManifest.xml 文件:main 和 debug。
这是必需的,因为您的应用需要通过 HTTP 与本机打包服务器 Metro 通信。
请确保只在debug 版本的清单文件中添加此配置。
4. 编写 TypeScript 代码
现在开始修改本机 Android 应用以集成 React Native。
首先编写的是新界面的 React Native 代码,这将被集成到应用中。
创建 index.js 文件
首先,在您的 React Native 项目根目录下创建一个空的 index.js 文件。
index.js 是 React Native 应用的入口文件,且始终必需。它可以是一个简单文件,import 其它 React Native 组件或应用的文件,也可以包含所有代码。
我们的 index.js 如下所示(参考社区模板):
import {AppRegistry} from 'react-native';
import App from './App';
AppRegistry.registerComponent('HelloWorld', () => App);
创建 App.tsx 文件
接下来创建 App.tsx,这是一个支持 TypeScript 和 JSX 语法的文件。它包含我们将集成到 Android 应用中的根 React Native 组件(参考链接):
import React from 'react';
import {
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
} from 'react-native';
import {
Colors,
DebugInstructions,
Header,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
function App(): React.JSX.Element {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
backgroundColor={backgroundStyle.backgroundColor}
/>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}>
<Header />
<View
style={{
backgroundColor: isDarkMode
? Colors.black
: Colors.white,
padding: 24,
}}>
<Text style={styles.title}>第一步</Text>
<Text>
编辑 <Text style={styles.bold}>App.tsx</Text> 来更改此页面内容,查看更改效果。
</Text>
<Text style={styles.title}>查看您的更改</Text>
<ReloadInstructions />
<Text style={styles.title}>调试</Text>
<DebugInstructions />
</View>
</ScrollView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
title: {
fontSize: 24,
fontWeight: '600',
},
bold: {
fontWeight: '700',
},
});
export default App;
这里是社区模板文件供参考。
5. 与您的 Android 代码集成
现在需要添加一些本机代码来启动 React Native 运行时并告诉它渲染哪些 React 组件。
更新 Application 类
首先,更新您的 Application 类,以正确初始化 React Native,如下所示:
- Java
- Kotlin
package <your-package-here>;
import android.app.Application;
+import com.facebook.react.PackageList;
+import com.facebook.react.ReactApplication;
+import com.facebook.react.ReactHost;
+import com.facebook.react.ReactNativeHost;
+import com.facebook.react.ReactPackage;
+import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
+import com.facebook.react.defaults.DefaultReactHost;
+import com.facebook.react.defaults.DefaultReactNativeHost;
+import com.facebook.soloader.SoLoader;
+import com.facebook.react.soloader.OpenSourceMergedSoMapping
+import java.util.List;
-class MainApplication extends Application {
+class MainApplication extends Application implements ReactApplication {
+ @Override
+ public ReactNativeHost getReactNativeHost() {
+ return new DefaultReactNativeHost(this) {
+ @Override
+ protected List<ReactPackage> getPackages() { return new PackageList(this).getPackages(); }
+ @Override
+ protected String getJSMainModuleName() { return "index"; }
+ @Override
+ public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; }
+ @Override
+ protected boolean isNewArchEnabled() { return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; }
+ @Override
+ protected Boolean isHermesEnabled() { return BuildConfig.IS_HERMES_ENABLED; }
+ };
+ }
+ @Override
+ public ReactHost getReactHost() {
+ return DefaultReactHost.getDefaultReactHost(getApplicationContext(), getReactNativeHost());
+ }
@Override
public void onCreate() {
super.onCreate();
+ SoLoader.init(this, OpenSourceMergedSoMapping);
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
+ DefaultNewArchitectureEntryPoint.load();
+ }
}
}
// package <your-package-here>
import android.app.Application
+import com.facebook.react.PackageList
+import com.facebook.react.ReactApplication
+import com.facebook.react.ReactHost
+import com.facebook.react.ReactNativeHost
+import com.facebook.react.ReactPackage
+import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
+import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
+import com.facebook.react.defaults.DefaultReactNativeHost
+import com.facebook.soloader.SoLoader
+import com.facebook.react.soloader.OpenSourceMergedSoMapping
-class MainApplication : Application() {
+class MainApplication : Application(), ReactApplication {
+ override val reactNativeHost: ReactNativeHost =
+ object : DefaultReactNativeHost(this) {
+ override fun getPackages(): List<ReactPackage> = PackageList(this).packages
+ override fun getJSMainModuleName(): String = "index"
+ override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
+ override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
+ override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
+ }
+ override val reactHost: ReactHost
+ get() = getDefaultReactHost(applicationContext, reactNativeHost)
override fun onCreate() {
super.onCreate()
+ SoLoader.init(this, OpenSourceMergedSoMapping)
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
+ load()
+ }
}
}
这里是社区模板中 MainApplication.kt 文件 以供参考。
创建 ReactActivity
最后,创建一个继承自 ReactActivity 的新 Activity,用以承载 React Native 代码。该 Activity 负责启动 React Native 运行时并渲染 React 组件。
- Java
- Kotlin
// package <your-package-here>;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactActivityDelegate;
public class MyReactActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "HelloWorld";
}
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new DefaultReactActivityDelegate(this, getMainComponentName(), DefaultNewArchitectureEntryPoint.getFabricEnabled());
}
}
// package <your-package-here>
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
class MyReactActivity : ReactActivity() {
override fun getMainComponentName(): String = "HelloWorld"
override fun createReactActivityDelegate(): ReactActivityDelegate =
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
}
这里是社区模板中 MainActivity.kt 文件 以供参考。
当您创建新的 Activity 时,需在 AndroidManifest.xml 文件中添加它。同时将 MyReactActivity 的主题设置为 Theme.AppCompat.Light.NoActionBar(或任意非 ActionBar 主题),否则应用界面顶部会渲染一个 ActionBar,影响 React Native 界面显示:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".MainApplication">
+ <activity
+ android:name=".MyReactActivity"
+ android:label="@string/app_name"
+ android:theme="@style/Theme.AppCompat.Light.NoActionBar">
+ </activity>
</application>
</manifest>
现在,您的 Activity 已准备好运行 JavaScript 代码。
6. 测试集成效果
您已经完成了所有基本步骤,将 React Native 集成到应用中。现在启动 Metro bundler 来构建您的 TypeScript 应用代码并打包。Metro 在开发环境的 localhost 通过 HTTP 向模拟器或设备共享 bundle,从而支持热重载。
首先,在项目根目录创建一个 metro.config.js 文件,内容如下:
const {getDefaultConfig} = require('@react-native/metro-config');
module.exports = getDefaultConfig(__dirname);
您可以参考社区模板中的 metro.config.js 文件。
配置完成后,在项目根目录运行以下命令启动打包器:
- npm
- Yarn
npm start
yarn start
接下来像平时一样构建并运行您的 Android 应用。
当您进入 React Native 控制的 Activity 时,它会从开发服务器加载 JavaScript 代码并显示如下界面:

使用 Android Studio 创建发布版本
您也可以使用 Android Studio 创建发布版本,流程与您之前创建原生 Android 应用的发布版本一样简单。
React Native Gradle 插件会自动将 JS 代码打包进 APK 或 App Bundle。
如果不使用 Android Studio,可以在命令行用以下命令创建发布版本:
cd android
# 创建 Release APK
./gradlew :app:assembleRelease
# 创建 Release AAB
./gradlew :app:bundleRelease
接下来做什么?
关键概念
将 React Native 组件集成到你的 iOS 应用中的关键步骤是:
- 设置正确的目录结构。
- 安装必要的 NPM 依赖。
- 在 Podfile 配置中添加 React Native。
- 为你的第一个 React Native 界面编写 TypeScript 代码。
- 使用
RCTRootView将 React Native 与你的 iOS 代码集成。 - 运行打包器测试集成效果,查看应用运行情况。
使用社区模板
在按照本指南操作时,我们建议你参考 React Native 社区模板。该模板包含一个 最小化的 iOS 应用,能帮助你理解如何将 React Native 集成到现有的 iOS 应用中。
前提条件
请先参照 设置开发环境指南 和 无框架使用 React Native 指南 配置好你的开发环境,以便为 iOS 构建 React Native 应用。
本指南还假设你熟悉 iOS 开发基础,比如创建 UIViewController 和编辑 Podfile 文件。
1. 设置目录结构
为确保顺利开发,请为你的集成 React Native 项目创建一个新文件夹,然后将现有的 iOS 项目 移动到 /ios 子文件夹中。
2. 安装 NPM 依赖
进入项目根目录,运行以下命令:
curl -O https://raw.githubusercontent.com/react-native-community/template/refs/heads/0.83-stable/template/package.json
这会将来自社区模板的 package.json 文件 拷贝到你的项目中。
接着,运行以下命令安装 NPM 包:
- npm
- Yarn
npm install
yarn install
安装过程会创建一个新的 node_modules 文件夹,该文件夹存放构建项目所需的所有 JavaScript 依赖。
请将 node_modules/ 添加到你的 .gitignore 文件中(这里是社区默认配置)。
3. 安装开发工具
Xcode 命令行工具
安装命令行工具。打开 Xcode 菜单,选择 设置…(或偏好设置…),进入 Locations 面板,在 “Command Line Tools” 下拉框中选择最新版本并安装。

CocoaPods
CocoaPods 是 iOS 和 macOS 开发的包管理工具。我们使用它将实际的 React Native 框架代码本地加入当前项目。
我们推荐通过 Homebrew 安装 CocoaPods:
brew install cocoapods
4. 将 React Native 添加到你的应用
配置 CocoaPods
配置 CocoaPods 需要两个文件:
- 一个定义需要哪些 Ruby 依赖的 Gemfile。
- 一个定义如何正确安装依赖的 Podfile。
对于 Gemfile,在项目根目录下运行:
curl -O https://raw.githubusercontent.com/react-native-community/template/refs/heads/0.83-stable/template/Gemfile
将从模板下载 Gemfile。
如果你是用 Xcode 16 创建的项目,需要按如下方式更新 Gemfile:
-gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
+gem 'cocoapods', '1.16.2'
gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
-gem 'xcodeproj', '< 1.26.0'
+gem 'xcodeproj', '1.27.0'
Xcode 16 生成项目的方式与以前版本略有不同,需要使用最新的 CocoaPods 和 Xcodeproj gem 才能正常工作。
同样,对于 Podfile,进入项目的 ios 文件夹,运行:
curl -O https://raw.githubusercontent.com/react-native-community/template/refs/heads/0.83-stable/template/ios/Podfile
请将社区模板作为 Gemfile 和 Podfile 的参考。
记得修改 此行。
接着,我们需要运行几条命令安装 Ruby gems 和 pods。
进入 ios 文件夹,执行:
bundle install
bundle exec pod install
第一个命令安装 Ruby 依赖,第二个将 React Native 代码集成到你的应用,使你的 iOS 文件可以导入 React Native 头文件。
5. 编写 TypeScript 代码
现在我们开始修改原生 iOS 应用,集成 React Native。
第一步编写的是将集成到应用中的新屏幕的 React Native 代码。
创建 index.js 文件
首先,在 React Native 项目根目录下创建一个空的 index.js。
index.js 是 React Native 应用的入口文件,必不可少。它可以是一个引入其他 React Native 组件文件的小文件,也可以包含所有代码。
我们的 index.js 应如下(此处参考社区模板文件):
import {AppRegistry} from 'react-native';
import App from './App';
AppRegistry.registerComponent('HelloWorld', () => App);
创建 App.tsx 文件
接下来创建 App.tsx 文件。它是一个可以包含 JSX 表达式的 TypeScript 文件,包含我们将要集成到 iOS 应用的根 React Native 组件(链接):
import React from 'react';
import {
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
} from 'react-native';
import {
Colors,
DebugInstructions,
Header,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
function App(): React.JSX.Element {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
backgroundColor={backgroundStyle.backgroundColor}
/>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}>
<Header />
<View
style={{
backgroundColor: isDarkMode
? Colors.black
: Colors.white,
padding: 24,
}}>
<Text style={styles.title}>第一步</Text>
<Text>
编辑 <Text style={styles.bold}>App.tsx</Text> 来修改此屏幕并查看你的修订。
</Text>
<Text style={styles.title}>查看修改</Text>
<ReloadInstructions />
<Text style={styles.title}>调试</Text>
<DebugInstructions />
</View>
</ScrollView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
title: {
fontSize: 24,
fontWeight: '600',
},
bold: {
fontWeight: '700',
},
});
export default App;
这里是 社区模板文件。
5. 与你的 iOS 代码集成
现在需要添加一些原生代码,启动 React Native 运行时并告诉它渲染我们的 React 组件。
要求
React Native 初始化现在不依赖于 iOS 应用的任意具体部分。
React Native 可以通过名为 RCTReactNativeFactory 的类来初始化,它帮你管理 React Native 生命周期。
初始化该类后,你可以用 UIWindow 对象启动 React Native 视图,或请求工厂生成一个 UIView,再加载到任意 UIViewController 中。
下面的例子中,我们将创建一个 ViewController,使其使用 React Native 视图作为它的 view。
创建 ReactViewController
新建一个文件(快捷键 ⌘+N),选择 Cocoa Touch Class 模板。
确保 “Subclass of” 字段选择 UIViewController。
- ObjectiveC
- Swift
打开 ReactViewController.m 文件,作如下修改:
#import "ReactViewController.h"
+#import <React/RCTBundleURLProvider.h>
+#import <RCTReactNativeFactory.h>
+#import <RCTDefaultReactNativeFactoryDelegate.h>
+#import <RCTAppDependencyProvider.h>
@interface ReactViewController ()
@end
+@interface ReactNativeFactoryDelegate: RCTDefaultReactNativeFactoryDelegate
+@end
-@implementation ReactViewController
+@implementation ReactViewController {
+ RCTReactNativeFactory *_factory;
+ id<RCTReactNativeFactoryDelegate> _factoryDelegate;
+}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
+ _factoryDelegate = [ReactNativeFactoryDelegate new];
+ _factoryDelegate.dependencyProvider = [RCTAppDependencyProvider new];
+ _factory = [[RCTReactNativeFactory alloc] initWithDelegate:_factoryDelegate];
+ self.view = [_factory.rootViewFactory viewWithModuleName:@"HelloWorld"];
}
@end
+@implementation ReactNativeFactoryDelegate
+
+- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
+{
+ return [self bundleURL];
+}
+
+- (NSURL *)bundleURL
+{
+#if DEBUG
+ return [RCTBundleURLProvider.sharedSettings jsBundleURLForBundleRoot:@"index"];
+#else
+ return [NSBundle.mainBundle URLForResource:@"main" withExtension:@"jsbundle"];
+#endif
+}
@end
打开 ReactViewController.swift 文件,作如下修改:
import UIKit
+import React
+import React_RCTAppDelegate
+import ReactAppDependencyProvider
class ReactViewController: UIViewController {
+ var reactNativeFactory: RCTReactNativeFactory?
+ var reactNativeFactoryDelegate: RCTReactNativeFactoryDelegate?
override func viewDidLoad() {
super.viewDidLoad()
+ reactNativeFactoryDelegate = ReactNativeDelegate()
+ reactNativeFactoryDelegate!.dependencyProvider = RCTAppDependencyProvider()
+ reactNativeFactory = RCTReactNativeFactory(delegate: reactNativeFactoryDelegate!)
+ view = reactNativeFactory!.rootViewFactory.view(withModuleName: "HelloWorld")
}
}
+class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
+ override func sourceURL(for bridge: RCTBridge) -> URL? {
+ self.bundleURL()
+ }
+
+ override func bundleURL() -> URL? {
+ #if DEBUG
+ RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
+ #else
+ Bundle.main.url(forResource: "main", withExtension: "jsbundle")
+ #endif
+ }
+
+}
在 rootViewController 中呈现 React Native 视图
最后,我们可以呈现 React Native 视图。为此需要一个能承载视图的新 View Controller,我们可以在这个视图中加载 JS 内容。
我们已有初始的 ViewController,可以让它弹出 ReactViewController。这可以通过多种方式实现,示例中假设你有一个按钮用于模态呈现 React Native 视图。
- ObjectiveC
- Swift
#import "ViewController.h"
+#import "ReactViewController.h"
@interface ViewController ()
@end
- @implementation ViewController
+@implementation ViewController {
+ ReactViewController *reactViewController;
+}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = UIColor.systemBackgroundColor;
+ UIButton *button = [UIButton new];
+ [button setTitle:@"Open React Native" forState:UIControlStateNormal];
+ [button setTitleColor:UIColor.systemBlueColor forState:UIControlStateNormal];
+ [button setTitleColor:UIColor.blueColor forState:UIControlStateHighlighted];
+ [button addTarget:self action:@selector(presentReactNative) forControlEvents:UIControlEventTouchUpInside];
+ [self.view addSubview:button];
+ button.translatesAutoresizingMaskIntoConstraints = NO;
+ [NSLayoutConstraint activateConstraints:@[
+ [button.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
+ [button.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
+ [button.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
+ [button.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
+ ]];
}
+- (void)presentReactNative
+{
+ if (reactViewController == NULL) {
+ reactViewController = [ReactViewController new];
+ }
+ [self presentViewController:reactViewController animated:YES];
+}
@end
import UIKit
class ViewController: UIViewController {
+ var reactViewController: ReactViewController?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.view.backgroundColor = .systemBackground
+ let button = UIButton()
+ button.setTitle("Open React Native", for: .normal)
+ button.setTitleColor(.systemBlue, for: .normal)
+ button.setTitleColor(.blue, for: .highlighted)
+ button.addAction(UIAction { [weak self] _ in
+ guard let self else { return }
+ if reactViewController == nil {
+ reactViewController = ReactViewController()
+ }
+ present(reactViewController!, animated: true)
+ }, for: .touchUpInside)
+ self.view.addSubview(button)
+
+ button.translatesAutoresizingMaskIntoConstraints = false
+ NSLayoutConstraint.activate([
+ button.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
+ button.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
+ button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
+ button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
+ ])
}
}
确保禁用 Sandbox 脚本。方法是在 Xcode 中点击你的应用,进入构建设置,搜索 script,将 “User Script Sandboxing” 设置为 NO。此步骤是为了正确切换我们与 React Native 一起发布的 Hermes 引擎 的调试和发布版本。

最后,确保在你的 Info.plist 文件中添加 UIViewControllerBasedStatusBarAppearance 键,并将其值设为 NO。

6. 测试你的集成
你已完成将 React Native 集成到应用的基本步骤。现在我们启动 Metro 打包器 将你的 TypeScript 代码打包成 bundle。Metro 的 HTTP 服务器会将 bundle 从开发环境的 localhost 共享到模拟器或设备,实现热更新。
首先,你需要在项目根目录创建一个 metro.config.js 文件,内容如下:
const {getDefaultConfig} = require('@react-native/metro-config');
module.exports = getDefaultConfig(__dirname);
你可以参考社区模板的 metro.config.js 文件。
然后,在项目根目录创建一个 .watchmanconfig 文件,内容是个空的 JSON 对象:
echo {} > .watchmanconfig
配置文件到位后,在项目根目录运行打包器:
- npm
- Yarn
npm start
yarn start
然后像往常一样构建并运行你的 iOS 应用。
进入 React 驱动的页面时,应用会从开发服务器加载 JavaScript 代码并显示:

在 Xcode 中创建发布版本
你也可以用 Xcode 创建发布版本!唯一额外步骤是在应用构建时添加一个脚本,负责打包 JS 和图片进 iOS 应用。
- 在 Xcode 选择你的应用
- 点击
Build Phases - 左上角点击
+,选择New Run Script Phase - 点击新建脚本行,将其重命名为
Bundle React Native code and images - 粘贴以下脚本
set -e
WITH_ENVIRONMENT="$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh"
REACT_NATIVE_XCODE="$REACT_NATIVE_PATH/scripts/react-native-xcode.sh"
/bin/sh -c "$WITH_ENVIRONMENT $REACT_NATIVE_XCODE"
- 将该脚本拖动到名为
[CP] Embed Pods Frameworks的脚本之前。
现在,如果你构建发布版本,应用能正常工作。
7. 向 React Native 视图传递初始属性
有时你想从原生应用向 JavaScript 传递信息。例如,你可能想将当前登录用户的 user id 和一个可用于数据库的 token 传给 React Native。
这可以通过 RCTReactNativeFactory 的 view(withModuleName:initialProperty) 重载版本的 initialProperties 参数实现。以下步骤演示如何操作。
更新 App.tsx 文件读取初始属性
打开 App.tsx 文件,加入如下代码:
import {
Colors,
DebugInstructions,
Header,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
-function App(): React.JSX.Element {
+function App(props): React.JSX.Element {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
backgroundColor={backgroundStyle.backgroundColor}
/>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}>
<Header />
- <View
- style={{
- backgroundColor: isDarkMode
- ? Colors.black
- : Colors.white,
- padding: 24,
- }}>
- <Text style={styles.title}>Step One</Text>
- <Text>
- Edit <Text style={styles.bold}>App.tsx</Text> to
- change this screen and see your edits.
- </Text>
- <Text style={styles.title}>See your changes</Text>
- <ReloadInstructions />
- <Text style={styles.title}>Debug</Text>
- <DebugInstructions />
+ <Text style={styles.title}>UserID: {props.userID}</Text>
+ <Text style={styles.title}>Token: {props.token}</Text>
</View>
</ScrollView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
title: {
fontSize: 24,
fontWeight: '600',
+ marginLeft: 20,
},
bold: {
fontWeight: '700',
},
});
export default App;
这些修改告诉 React Native,你的 App 组件现在接收一些属性。RCTReactNativeFactory 会负责渲染时传递它们。
修改原生代码,将初始属性传递给 JavaScript
- ObjectiveC
- Swift
修改 ReactViewController.mm,向 JavaScript 传递初始属性:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_factoryDelegate = [ReactNativeFactoryDelegate new];
_factoryDelegate.dependencyProvider = [RCTAppDependencyProvider new];
_factory = [[RCTReactNativeFactory alloc] initWithDelegate:_factoryDelegate];
- self.view = [_factory.rootViewFactory viewWithModuleName:@"HelloWorld"];
+ self.view = [_factory.rootViewFactory viewWithModuleName:@"HelloWorld" initialProperties:@{
+ @"userID": @"12345678",
+ @"token": @"secretToken"
+ }];
}
修改 ReactViewController.swift,向 React Native 视图传递初始属性:
override func viewDidLoad() {
super.viewDidLoad()
reactNativeFactoryDelegate = ReactNativeDelegate()
reactNativeFactoryDelegate!.dependencyProvider = RCTAppDependencyProvider()
reactNativeFactory = RCTReactNativeFactory(delegate: reactNativeFactoryDelegate!)
- view = reactNativeFactory!.rootViewFactory.view(withModuleName: "HelloWorld")
+ view = reactNativeFactory!.rootViewFactory.view(withModuleName: "HelloWorld" initialProperties: [
+ "userID": "12345678",
+ "token": "secretToken"
+])
}
}
- 再次运行你的应用。弹出
ReactViewController后,应该看到如下界面:
