React Native原生模块 #
概述 #
当 React Native 没有提供某些功能时,可以通过原生模块来访问平台特有的 API。本章节介绍如何创建和使用原生模块。
iOS 原生模块 #
创建模块 #
- 创建 Objective-C 文件
RCTCalendarModule.h:
objc
#import <React/RCTBridgeModule.h>
@interface RCTCalendarModule : NSObject <RCTBridgeModule>
@end
- 创建实现文件
RCTCalendarModule.m:
objc
#import "RCTCalendarModule.h"
@implementation RCTCalendarModule
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(addEvent:(NSString *)name
location:(NSString *)location
date:(NSString *)date)
{
NSLog(@"Add event: %@ at %@ on %@", name, location, date);
}
RCT_REMAP_METHOD(getEvents,
getEventsWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSArray *events = @[@"Event 1", @"Event 2", @"Event 3"];
resolve(events);
}
@end
导出常量 #
objc
- (NSDictionary *)constantsToExport
{
return @{ @"version": @"1.0.0" };
}
支持线程 #
objc
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
Swift 原生模块 #
- 创建 Swift 文件
CalendarModule.swift:
swift
import Foundation
@objc(CalendarModule)
class CalendarModule: NSObject {
@objc
func addEvent(_ name: String, location: String, date: String) {
print("Add event: \(name) at \(location) on \(date)")
}
@objc
func getEvents(_ resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
let events = ["Event 1", "Event 2", "Event 3"]
resolve(events)
}
@objc
static func requiresMainQueueSetup() -> Bool {
return true
}
}
- 创建桥接文件
CalendarModuleBridge.m:
objc
#import <React/RCTBridgeModule.h>
@interface RCT_EXTERN_MODULE(CalendarModule, NSObject)
RCT_EXTERN_METHOD(addEvent:(NSString *)name
location:(NSString *)location
date:(NSString *)date)
RCT_EXTERN_METHOD(getEvents:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)
@end
Android 原生模块 #
创建模块 #
- 创建 Java 文件
CalendarModule.java:
java
package com.myapp;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;
import com.facebook.react.module.annotations.ReactModule;
@ReactModule(name = CalendarModule.NAME)
public class CalendarModule extends ReactContextBaseJavaModule {
public static final String NAME = "CalendarModule";
public CalendarModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return NAME;
}
@ReactMethod
public void addEvent(String name, String location, String date) {
System.out.println("Add event: " + name + " at " + location + " on " + date);
}
@ReactMethod
public void getEvents(Promise promise) {
try {
WritableArray events = Arguments.createArray();
events.pushString("Event 1");
events.pushString("Event 2");
events.pushString("Event 3");
promise.resolve(events);
} catch (Exception e) {
promise.reject("ERROR", e.getMessage());
}
}
}
创建包 #
java
package com.myapp;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.bridge.ReactApplicationContext;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CalendarPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new CalendarModule(reactContext));
return modules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
注册包 #
在 MainApplication.java 中:
java
@Override
protected List<ReactPackage> getPackages() {
List<ReactPackage> packages = new PackageList(this).getPackages();
packages.add(new CalendarPackage());
return packages;
}
Kotlin 原生模块 #
kotlin
package com.myapp
import com.facebook.react.bridge.*
import com.facebook.react.module.annotations.ReactModule
@ReactModule(name = CalendarModule.NAME)
class CalendarModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
companion object {
const val NAME = "CalendarModule"
}
override fun getName(): String = NAME
@ReactMethod
fun addEvent(name: String, location: String, date: String) {
println("Add event: $name at $location on $date")
}
@ReactMethod
fun getEvents(promise: Promise) {
try {
val events = Arguments.createArray()
events.pushString("Event 1")
events.pushString("Event 2")
events.pushString("Event 3")
promise.resolve(events)
} catch (e: Exception) {
promise.reject("ERROR", e.message)
}
}
}
JavaScript 调用 #
基本调用 #
tsx
import {NativeModules} from 'react-native';
const {CalendarModule} = NativeModules;
const addEvent = async () => {
CalendarModule.addEvent('Meeting', 'Office', '2024-01-15');
};
const getEvents = async () => {
try {
const events = await CalendarModule.getEvents();
console.log('Events:', events);
} catch (error) {
console.error('Error:', error);
}
};
TypeScript 类型定义 #
创建 NativeCalendarModule.ts:
tsx
declare module 'react-native' {
interface NativeModulesStatic {
CalendarModule: {
addEvent(name: string, location: string, date: string): void;
getEvents(): Promise<string[]>;
version: string;
};
}
}
事件发送 #
iOS 发送事件 #
objc
#import "CalendarModule.h"
#import <React/RCTEventEmitter.h>
@interface CalendarModule () <RCTEventEmitter>
@end
@implementation CalendarModule
RCT_EXPORT_MODULE();
- (NSArray<NSString *> *)supportedEvents {
return @[@"onEventAdded"];
}
- (void)sendEventAdded:(NSString *)eventName {
[self sendEventWithName:@"onEventAdded" body:@{@"name": eventName}];
}
@end
Android 发送事件 #
java
public class CalendarModule extends ReactContextBaseJavaModule {
private static final String EVENT_NAME = "onEventAdded";
public void sendEventAdded(String eventName) {
ReactApplicationContext context = getReactApplicationContext();
WritableMap params = Arguments.createMap();
params.putString("name", eventName);
context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(EVENT_NAME, params);
}
}
JavaScript 监听事件 #
tsx
import {NativeEventEmitter, NativeModules} from 'react-native';
const {CalendarModule} = NativeModules;
const eventEmitter = new NativeEventEmitter(CalendarModule);
useEffect(() => {
const subscription = eventEmitter.addListener('onEventAdded', event => {
console.log('Event added:', event.name);
});
return () => {
subscription.remove();
};
}, []);
原生 UI 组件 #
iOS 原生视图 #
objc
#import <React/RCTViewManager.h>
@interface MyViewManager : RCTViewManager
@end
@implementation MyViewManager
RCT_EXPORT_MODULE()
- (UIView *)view
{
UILabel *label = [[UILabel alloc] init];
label.text = @"Hello from native!";
return label;
}
RCT_EXPORT_VIEW_PROPERTY(text, NSString)
@end
Android 原生视图 #
java
public class MyViewManager extends SimpleViewManager<TextView> {
public static final String REACT_CLASS = "MyView";
@Override
public String getName() {
return REACT_CLASS;
}
@Override
protected TextView createViewInstance(ThemedReactContext reactContext) {
TextView textView = new TextView(reactContext);
textView.setText("Hello from native!");
return textView;
}
@ReactProp(name = "text")
public void setText(TextView view, String text) {
view.setText(text);
}
}
JavaScript 使用 #
tsx
import {requireNativeComponent} from 'react-native';
interface MyViewProps {
text: string;
style?: any;
}
const MyView = requireNativeComponent<MyViewProps>('MyView');
const App = () => {
return <MyView text="Hello" style={{width: 200, height: 50}} />;
};
新架构:TurboModules #
概述 #
TurboModules 是 React Native 新架构的一部分,提供更好的类型安全和性能。
定义接口 #
创建 NativeCalendarModule.ts:
typescript
export interface Spec extends TurboModule {
addEvent(name: string, location: string, date: string): Promise<void>;
getEvents(): Promise<string[]>;
getConstants(): {
version: string;
};
}
export default TurboModuleRegistry.getEnforcing<Spec>('CalendarModule');
Codegen 配置 #
在 package.json 中:
json
{
"codegenConfig": {
"name": "MyAppSpec",
"type": "modules",
"jsSrcsDir": "src/native"
}
}
最佳实践 #
错误处理 #
tsx
const safeNativeCall = async <T>(
nativeMethod: () => Promise<T>,
fallback?: T,
): Promise<T | undefined> => {
try {
return await nativeMethod();
} catch (error) {
console.error('Native call failed:', error);
return fallback;
}
};
// 使用
const events = await safeNativeCall(
() => CalendarModule.getEvents(),
[],
);
平台检测 #
tsx
import {Platform, NativeModules} from 'react-native';
const getNativeModule = () => {
if (Platform.OS === 'ios') {
return NativeModules.IOSCalendarModule;
} else {
return NativeModules.AndroidCalendarModule;
}
};
模块可用性检查 #
tsx
const isModuleAvailable = (moduleName: string): boolean => {
return NativeModules[moduleName] !== undefined;
};
if (isModuleAvailable('CalendarModule')) {
CalendarModule.getEvents();
} else {
console.warn('CalendarModule not available');
}
总结 #
原生模块要点:
- iOS:使用 Objective-C 或 Swift
- Android:使用 Java 或 Kotlin
- 导出方法:使用 RCT_EXPORT_METHOD / @ReactMethod
- Promise:异步操作返回 Promise
- 事件发送:使用 RCTEventEmitter
- 原生视图:创建自定义 UI 组件
- 新架构:使用 TurboModules
继续学习 性能优化,了解应用性能调优技巧。
最后更新:2026-03-28