Integration with Existing Apps
React Native is great when you are starting a new mobile app from scratch. However, it also works well for adding a single view or user flow to existing native applications. With a few steps, you can add new React Native based features, screens, views, etc.
The specific steps are different depending on what platform you're targeting.
- Android (Java & Kotlin)
- iOS (Objective-C and Swift)
核心概念
将 React Native 组件集成到 Android 应用中的关键在于:
- 设置正确的目录结构。
- 安装必要的 NPM 依赖。
- 将 React Native 添加到你的 Gradle 配置中。
- 编写第一个 React Native 屏幕的 TypeScript 代码。
- 使用
ReactActivity将 React Native 与你的 Android 代码集成。 - 运行打包器并查看应用实际效果,以测试集成结果。
使用社区模板
在按照本指南操作时,我们建议你将 React Native Community Template 作为参考。该模板包含一个最小化的 Android 应用,并将帮助你理解如何将 React Native 集成到现有的 Android 应用中。
前提条件
请先按照 配置开发环境 和 在没有框架的情况下使用 React Native 中的指南配置你的开发环境,以便构建 Android 版 React Native 应用。
本指南还假设你已经熟悉 Android 开发基础,例如创建 Activity 和编辑 AndroidManifest.xml 文件。
1. 设置目录结构
为了确保顺畅的开发体验,请为集成 React Native 的项目创建一个新文件夹,然后将你现有的 Android 项目移动到 /android 子文件夹中。
2. 安装 NPM 依赖
进入根目录并运行以下命令:
curl -O https://raw.githubusercontent.com/react-native-community/template/refs/heads/main/template/package.json
这会将社区模板中的 package.json 文件复制到你的项目中。
接下来,运行以下命令安装 NPM 包:
- npm
- Yarn
npm install
yarn install
安装过程会创建一个新的 node_modules 文件夹。这个文件夹用于存放构建项目所需的所有 JavaScript 依赖项。
将 node_modules/ 添加到你的 .gitignore 文件中(这里使用 社区默认版本)。
3. 将 React Native 添加到你的应用中
配置 Gradle
React Native 使用 React Native Gradle Plugin 来配置你的依赖项和项目设置。
首先,编辑你的 settings.gradle 文件并添加这些行(如 社区模板 所建议):
// 配置用于自动链接的 React Native Gradle Settings 插件
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 Plugin(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>
然后,你需要在调试用的 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 通信。
请确保只将其添加到你的调试清单文件中。
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 文件。这是一个可以包含 JSX 表达式的 TypeScript 文件。它包含我们将集成到 Android 应用中的根 React Native 组件(链接):
import {type JSX} 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(): 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
最后,我们需要创建一个新的 Activity,它将继承 ReactActivity 并承载 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 主题),否则你的应用会在 React Native 屏幕顶部渲染一个 ActionBar:
<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 应用代码构建成一个 bundle。Metro 的 HTTP 服务器会将你开发环境中 localhost 上的 bundle 分享到模拟器或设备。这使得 热重载 成为可能。
首先,你需要在项目根目录中创建一个 metro.config.js 文件,如下所示:
const {getDefaultConfig} = require('@react-native/metro-config');
module.exports = getDefaultConfig(__dirname);
你可以参考 Community 模板文件中的 metro.config.js 文件。
配置文件就位后,你就可以运行 bundler 了。在项目根目录下运行以下命令:
- npm
- Yarn
npm start
yarn start
现在像平常一样构建并运行你的 Android 应用。
一旦你进入应用中的 React 驱动 Activity,它就应该会从开发服务器加载 JavaScript 代码并显示:

在 Android Studio 中创建发布构建
你也可以使用 Android Studio 来创建发布构建!这和为你之前已有的原生 Android 应用创建发布构建一样快捷。
React Native Gradle Plugin 会负责将 JS 代码打包到你的 APK/App Bundle 中。
如果你不使用 Android Studio,可以通过以下方式创建发布构建:
cd android
# 对于 Release APK
./gradlew :app:assembleRelease
# 对于 Release AAB
./gradlew :app:bundleRelease
接下来呢?
此时你可以像往常一样继续开发你的应用。请参考我们的 调试 和 部署 文档,了解更多有关使用 React Native 的内容。
关键概念
将 React Native 组件集成到你的 iOS 应用中的关键步骤是:
- 设置正确的目录结构。
- 安装必要的 NPM 依赖。
- 将 React Native 添加到你的 Podfile 配置中。
- 编写第一个 React Native 屏幕的 TypeScript 代码。
- 使用
RCTRootView将 React Native 与你的 iOS 代码集成。 - 运行打包器并查看应用实际运行效果,以测试你的集成。
使用社区模板
在按照本指南操作时,我们建议你将 React Native Community Template 作为参考。该模板包含一个最小化的 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/main/template/package.json
这会将 Community 模板中的 package.json 文件复制到你的项目中。
接下来,运行以下命令安装 NPM 包:
- npm
- Yarn
npm install
yarn install
安装过程会创建一个新的 node_modules 文件夹。该文件夹会存储构建项目所需的所有 JavaScript 依赖项。
将 node_modules/ 添加到你的 .gitignore 文件中(这里使用的是 Community 默认版本)。
3. 安装开发工具
Xcode 命令行工具
安装命令行工具。在 Xcode 菜单中选择 Settings...(或 Preferences...)。进入 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/main/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/main/template/ios/Podfile
请将 Community Template 作为 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 应用的入口点,并且始终是必需的。它可以是一个很小的文件,用于 import 其他属于 React Native 组件或应用的文件;也可以包含所需的全部代码。
我们的 index.js 应如下所示(这里将 Community 模板文件作为参考):
import {AppRegistry} from 'react-native';
import App from './App';
AppRegistry.registerComponent('HelloWorld', () => App);
创建 App.tsx 文件
让我们创建一个 App.tsx 文件。这是一个可以包含 JSX 表达式的 TypeScript 文件。它包含我们将集成到 iOS 应用中的根 React Native 组件(链接):
import {type JSX} 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(): 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;
这里是 Community 模板文件作为参考。
5. 将其与 iOS 代码集成
现在我们需要添加一些原生代码,以启动 React Native 运行时并告诉它渲染我们的 React 组件。
要求
React Native 的初始化现在不再绑定到 iOS 应用中的任何特定部分。
React Native 可以使用一个名为 RCTReactNativeFactory 的类来初始化,该类会为你处理 React Native 的生命周期。
类初始化后,你可以通过提供一个 UIWindow 对象来启动 React Native 视图,或者让工厂生成一个可以加载到任意 UIViewController 中的 UIView。
在下面的示例中,我们将创建一个可以将 React Native 视图作为其 view 加载的 ViewController。
创建 ReactViewController
通过模板创建一个新文件(⌘+N),然后选择 Cocoa Touch Class 模板。
确保将 UIViewController 选为 “Subclass of” 字段。
- 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 scripting。为此,在 Xcode 中点击你的应用,然后进入 build settings。筛选 script,并将 User Script Sandboxing 设为 NO。此步骤对于在我们随 React Native 一起发布的 Hermes 引擎 的 Debug 和 Release 版本之间正确切换是必需的。

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

6. 测试你的集成
你已经完成了将 React Native 集成到应用中的所有基础步骤。现在我们将启动 Metro bundler,把你的 TypeScript 应用代码构建成一个 bundle。Metro 的 HTTP 服务器会将位于开发环境中 localhost 的 bundle 共享给模拟器或设备。这使得 热重载 成为可能。
首先,你需要在项目根目录下创建一个 metro.config.js 文件,如下所示:
const {getDefaultConfig} = require('@react-native/metro-config');
module.exports = getDefaultConfig(__dirname);
你可以从 Community 模板文件中查看 metro.config.js 文件 作为参考。
然后,你需要在项目根目录下创建一个 .watchmanconfig 文件。该文件必须包含一个空的 JSON 对象:
echo {} > .watchmanconfig
配置文件准备好后,就可以运行 bundler 了。在项目根目录下执行以下命令:
- npm
- Yarn
npm start
yarn start
现在按常规方式构建并运行你的 iOS 应用。
当你到达应用内由 React 驱动的 Activity 时,它应该会从开发服务器加载 JavaScript 代码并显示:

在 Xcode 中创建发布构建
你也可以使用 Xcode 来创建发布构建!唯一额外需要的一步是添加一个脚本,它会在应用构建时执行,用于将你的 JS 和图片打包进 iOS 应用中。
- 在 Xcode 中选择你的应用
- 点击
Build Phases - 点击左上角的
+,然后选择New Run Script Phase - 点击
Run Script这一行,并将 Script 重命名为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之前。
现在,如果你构建 Release 版本的应用,它将按预期工作。
7. 向 React Native 视图传递初始属性
在某些情况下,你可能希望从原生应用向 JavaScript 传递一些信息。例如,你可能想把当前登录用户的用户 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后,应该会看到以下界面:

接下来呢?
到这里,你可以像平常一样继续开发你的应用。请参阅我们的 调试 和 部署 文档,了解更多关于使用 React Native 的内容。