You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native新架构中内置TurboModule出现undefined问题

问题描述

我正尝试在React Native应用内创建TurboModule(而非独立模块),已完成以下操作:

  1. 创建RTNCalculator文件夹及其中的js子目录,新建NativeCalculator.ts定义TurboModule接口
  2. 在应用package.json中添加codegenConfig配置
  3. 执行./gradlew generateCodegenArtifactsFromSchema命令,在Android主目录生成CalculatorModule.kt和CalculatorPackage.kt
  4. 在MainApplication.java中添加packages.add(new CalculatorPackage());
  5. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 19:00:32