React Native新架构中内置TurboModule出现undefined问题
问题描述
我正尝试在React Native应用内创建TurboModule(而非独立模块),已完成以下操作:
- 创建
RTNCalculator文件夹及其中的js子目录,新建NativeCalculator.ts定义TurboModule接口 - 在应用
package.json中添加codegenConfig配置 - 执行
./gradlew generateCodegenArtifactsFromSchema命令,在Android主目录生成CalculatorModule.kt和CalculatorPackage.kt - 在
MainApplication.java中添加packages.add(new CalculatorPackage()); - 在
App.tsx中导入并调用RTNCalculator.add(),但返回undefined(已开启新架构)
NativeCalculator.ts代码:
import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport'; import {TurboModuleRegistry} from 'react-native'; export interface Spec extends TurboModule { add(a: number, b: number): Promise<number>; pickImage(): Promise<void>; someDummyMethod(): Promise<void>; addTwo(a: number, b: number): Promise<number>; } export default TurboModuleRegistry.get<Spec>('RTNCalculator') as Spec | null;
CalculatorPackage.kt代码:
class CalculatorPackage : TurboReactPackage() { override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? { return if (name == CalculatorModule.NAME) { CalculatorModule(reactContext) } else { null } } override fun getReactModuleInfoProvider(): ReactModuleInfoProvider? { return ReactModuleInfoProvider { val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap() moduleInfos[CalculatorModule.NAME] = ReactModuleInfo( CalculatorModule.NAME, CalculatorModule.NAME, false, // canOverrideExistingModule false, // needsEagerInit true, // hasConstants false, // isCxxModule true // isTurboModule ) moduleInfos } } }
CalculatorModule.kt代码:
class CalculatorModule(context: ReactApplicationContext): NativeCalculatorSpec(context) { override fun getName(): String { return NAME } override fun add(a: Double, b: Double, promise: Promise?) { promise!!.resolve(a+b) } override fun pickImage(promise: Promise?) { } override fun someDummyMethod(promise: Promise?) { } override fun addTwo(a: Double, b: Double, promise: Promise?) { } companion object { const val NAME = "RTNCalculator" } }
解决方案
以下是可能遗漏的关键步骤:
1. 校验codegenConfig配置正确性
确保package.json中的codegenConfig正确指向你的TurboModule接口文件,示例配置如下:
"codegenConfig": { "name": "RTNCalculatorSpec", "type": "modules", "jsSrcsDir": "./RTNCalculator/js", "android": { "javaPackageName": "com.tmtry" // 替换为你的Android应用包名 } }
配置后执行yarn install(或npm install)触发Codegen处理JS接口,生成对应的Native层Spec文件。
2. 确保Codegen生成的Spec文件被正确引用
CalculatorModule继承的NativeCalculatorSpec是Codegen自动生成的类,需确认:
- 该类位于
codegenConfig.android.javaPackageName指定的包路径下(如com.tmtry) CalculatorModule.kt文件的包声明与生成的Spec包名一致,例如顶部添加:package com.tmtry
3. 检查TurboModule的调用逻辑
在App.tsx中调用模块前,需先判断模块是否成功注册,避免直接调用undefined:
import RTNCalculator from './RTNCalculator/js/NativeCalculator'; // 调用示例 const handleAdd = async () => { if (!RTNCalculator) { console.error("RTNCalculator TurboModule未找到"); return; } try { const result = await RTNCalculator.add(1, 2); console.log("计算结果:", result); } catch (error) { console.error("调用失败:", error); } };
4. 修复Android端Promise处理逻辑
CalculatorModule中直接使用promise!!可能导致空指针异常,建议修改为安全的判空处理:
override fun add(a: Double, b: Double, promise: Promise?) { promise?.resolve(a + b) ?: run { promise?.reject("MODULE_ERROR", "Promise对象为空") } }
5. 确认新架构配置完全生效
检查gradle.properties中是否开启新架构:
newArchEnabled=true
同时执行./gradlew clean && ./gradlew assembleDebug重新构建项目,确保新架构配置同步生效。
内容的提问来源于stack exchange,提问作者BraveEvidence
相关产品推荐
相关产品推荐

