与现有应用集成
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 代码集成
- 运行 bundler 并查看应用运行效果,以测试集成
使用 Community Template
在遵循本指南的过程中,我们建议你参考 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/0.87-stable/template/package.json
这会将 Community template 中的 package.json 文件复制到你的项目中。
接下来,运行以下命令安装 NPM 包:
- npm
- Yarn
npm install
yarn install
安装过程会创建一个新的 node_modules 文件夹。该文件夹存储构建项目所需的所有 JavaScript 依赖。
将 node_modules/ 添加到你的 .gitignore 文件中(此处为 Community 默认文件)。
3. 将 React Native 添加到你的应用中
配置 Gradle
React Native 使用 React Native Gradle Plugin 来配置依赖和项目设置。
首先,按照以下方式编辑 settings.gradle 文件,添加这些代码行(如 Community template 中所示):
// Configures the React Native Gradle Settings plugin used for autolinking
pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }
plugins { id("com.facebook.react.settings") }
extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
// If using .gradle.kts files:
// extensions.configure<com.facebook.react.ReactSettingsExtension> { autolinkLibrariesFromCommand() }
includeBuild("../node_modules/@react-native/gradle-plugin")
// Include your existing Gradle modules here.
// include(":app")
然后打开顶层的 build.gradle,并添加以下代码行(如 Community template 中所示):
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 文件夹中——你可以参考 Community template 文件):
apply plugin: "com.android.application"
+apply plugin: "com.facebook.react"
repositories {
mavenCentral()
}
dependencies {
// Other dependencies here
+ // Note: we intentionally don't specify the version number here as RNGP will take care of it.
+ // If you don't use the RNGP, you'll have to specify version manually.
+ implementation("com.facebook.react:react-android")
+ implementation("com.facebook.react:hermes-android")
}
+react {
+ // Needed to enable Autolinking - https://github.com/react-native-community/cli/blob/master/docs/autolinking.md
+ autolinkLibrariesWithApp()
+}
最后,打开应用的 gradle.properties 文件,并添加以下代码行(此处可参考 Community template 文件):
+reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
+newArchEnabled=true
+hermesEnabled=true
配置 manifest
首先,确保你的 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>
和往常一样,以下是 Community template 中的 AndroidManifest.xml 文件,可供参考:main 和 debug。
这是必需的,因为你的应用将通过 HTTP 与本地 bundler Metro 通信。
请确保只将其添加到你的调试 manifest 中。
4. 编写 TypeScript 代码
现在,我们将实际修改原生 Android 应用,以集成 React Native。
我们要编写的第一段代码,是将要集成到应用中的新屏幕对应的 React Native 代码。
创建 index.js 文件
首先,在 React Native 项目的根目录中创建一个空的 index.js 文件。
index.js 是 React Native 应用的入口点,并且始终是必需的。它可以是一个用于 import React Native 组件或应用中其他文件的小文件,也可以包含运行该组件或应用所需的全部代码。
我们的 index.js 应如下所示(此处可参考 Community template 文件):
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}>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 />
</View>
</ScrollView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
title: {
fontSize: 24,
fontWeight: '600',
},
bold: {
fontWeight: '700',
},
});
export default App;
以下是 Community template 文件,可供参考。
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()
+ }
}
}
和往常一样,以下是 Community template 中的 MainApplication.kt 文件,可供参考。
创建一个 ReactActivity
最后,我们需要创建一个继承 ReactActivity 并承载 React Native 代码的新 Activity。该 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)
}
和往常一样,以下是 Community template 中的 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 template 中查看 metro.config.js 文件,以供参考。
准备好配置文件后,就可以运行 bundler 了。在项目根目录中运行以下命令:
- npm
- Yarn
npm start
yarn start
现在,像平常一样构建并运行你的 Android 应用。
当你在应用中进入由 React 驱动的 Activity 后,它应从开发服务器加载 JavaScript 代码并显示:

在 Android Studio 中创建 release 构建
你也可以使用 Android Studio 创建 release 构建!这与为之前已有的原生 Android 应用创建 release 构建一样快捷。
React Native Gradle Plugin 会负责将 JS 代码打包到你的 APK/App Bundle 中。
如果你不使用 Android Studio,可以通过以下方式创建 release 构建:
cd android
# For a Release APK
./gradlew :app:assembleRelease
# For a Release AAB
./gradlew :app:bundleRelease
接下来做什么?
核心概念
将 React Native 组件集成到 iOS 应用中的关键步骤是:
- 设置正确的目录结构
- 安装必要的 NPM 依赖
- 将 React Native 添加到 Podfile 配置中
- 为第一个 React Native 屏幕编写 TypeScript 代码
- 使用
RCTRootView将 React Native 与 iOS 代码集成 - 通过运行 bundler 并查看应用运行效果来测试集成
使用 Community Template
在遵循本指南的过程中,我们建议你参考 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/0.87-stable/template/package.json
这会将 Community template 中的 package.json 文件复制到你的项目中
接下来,运行以下命令安装 NPM 软件包:
- npm
- Yarn
npm install
yarn install
安装过程创建了一个新的 node_modules 文件夹。此文件夹存储构建项目所需的所有 JavaScript 依赖
将 node_modules/ 添加到你的 .gitignore 文件中(这里提供了 Community 的默认文件)
3.安装开发工具
Xcode 的 Command Line Tools
安装 Command Line Tools。在 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/0.87-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 生成项目的方式与之前版本的 Xcode 略有不同,你需要最新的 CocoaPods 和 Xcodeproj gems 才能使其正常工作
同样,对于 Podfile,进入项目的 ios 文件夹并运行
curl -O https://raw.githubusercontent.com/react-native-community/template/refs/heads/0.87-stable/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 应用的起始点,并且始终是必需的。它可以是一个导入 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}>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 />
</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 应用的任何特定部分
可以使用名为 RCTReactNativeFactory 的类初始化 React Native,该类负责处理 React Native 的生命周期
初始化该类后,你可以提供一个 UIWindow 对象来启动 React Native 视图,也可以让 factory 生成一个 UIView,然后在任意 UIViewController 中加载它
在下面的示例中,我们将创建一个可以将 React Native 视图作为其 view 加载的 ViewController
创建 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 scripting。要实现这一点,请在 Xcode 中点击你的应用,然后进入构建设置。筛选 script,并将 User Script Sandboxing 设置为 NO。为了在 React Native 随附的 Hermes engine 的 Debug 和 Release 版本之间正确切换,需要执行此步骤

最后,请确保将 UIViewControllerBasedStatusBarAppearance 键添加到 Info.plist 文件中,并将值设置为 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 template 中查看 metro.config.js 文件,以此作为参考
然后,你需要在项目根目录中创建一个 .watchmanconfig 文件。该文件必须包含一个空的 json 对象:
echo {} > .watchmanconfig
配置文件准备就绪后,就可以运行 bundler。在项目根目录中运行以下命令:
- npm
- Yarn
npm start
yarn start
现在,像平常一样构建并运行 iOS 应用
当你在应用中进入由 React 驱动的 Activity 后,它应该会从开发服务器加载 JavaScript 代码并显示:

在 Xcode 中创建 Release 构建
你也可以使用 Xcode 创建 Release 构建!唯一的额外步骤是添加一个在应用构建时执行的脚本,将 JS 和图像打包到 iOS 应用中
- 在 Xcode 中选择你的应用
- 点击
Build Phases - 点击左上角的
+,然后选择New Run Script Phase - 点击
Run 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 视图传递初始 props
在某些情况下,你可能希望将一些信息从 Native 应用传递给 JavaScript。例如,你可能希望将当前登录用户的用户 ID,以及可用于从数据库检索信息的令牌传递给 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 会负责在组件渲染时将这些属性传递给它
更新 Native 代码,将初始属性传递给 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后,你应该会看到以下屏幕:

接下来做什么?
现在,你可以继续像平常一样开发应用。请参考我们的 debugging 和 deployment 文档,进一步了解如何使用 React Native。