React Native中‘undefined is not an object (evaluating 'u.Foo')’错误修复咨询
问题:Xamarin与React Native桥接时NativeModule调用失败
问题背景
我正在开发Xamarin与React Native之间的桥接应用,参考相关项目实现,但点击按钮调用原生模块时出现错误,无法触发原生端的Foo方法。
相关代码
NativePackage.cs
using Com.Facebook.React.Bridge; using Com.Facebook.React.Uimanager; using Com.Facebook.React; using Java.Interop; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Android.Widget; using Android.Content; namespace ReactNative.Droid { public class NativePackage : Java.Lang.Object, IReactPackage { public IList<INativeModule> CreateNativeModules(ReactApplicationContext context) { var module = new NativeModule(context); var list = new List<INativeModule> { module }; Console.WriteLine("Hello CreateNativeModules"); return list; } public IList<ViewManager> CreateViewManagers(ReactApplicationContext context) { Console.WriteLine("Hello CreateViewManagers"); return new List<ViewManager> { }; } } public class NativeModule : ReactContextBaseJavaModule { public NativeModule(ReactApplicationContext reactContext) : base(reactContext) { Console.WriteLine("Hello NativeModule"); } public override string Name => "XNativeModule"; [Export("Foo")] [ReactMethod] public void Foo() { Console.WriteLine("Hello Native World"); Toast.MakeText(ReactApplicationContext, "Hello Native World", ToastLength.Long).Show(); } } }
MainActivity.cs
using Android.App; using Android.OS; using Com.Facebook.React; using Com.Facebook.React.Shell; using Com.Facebook.React.Common; using Android.Views; using Com.Facebook.React.Modules.Core; using Android.Support.V7.App; using Android.Content; using Android.Net; using Android.Provider; using ReactNative.Droid; namespace SampleApp.Droid { [Activity(Label = "XamarinReactNative", MainLauncher = true, Icon = "@mipmap/icon", Theme = "@style/Theme.AppCompat.Light.NoActionBar")] public class MainActivity : AppCompatActivity, IDefaultHardwareBackBtnHandler { ReactRootView mReactRootView; ReactInstanceManager mReactInstanceManager; private const int OVERLAY_PERMISSION_REQ_CODE = 1; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); if (Build.VERSION.SdkInt >= BuildVersionCodes.M) { if (!Settings.CanDrawOverlays(this)) { Intent intent = new Intent(Settings.ActionManageOverlayPermission, Uri.Parse("package:" + PackageName)); StartActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE); } } mReactRootView = new ReactRootView(this); mReactInstanceManager = ReactInstanceManager.Builder() .SetApplication(Application) .SetBundleAssetName("index.android.bundle") .SetJSMainModulePath("index") .AddPackage(new MainReactPackage()) #if DEBUG .SetUseDeveloperSupport(true) #else .SetUseDeveloperSupport(false) #endif .SetInitialLifecycleState(LifecycleState.Resumed) .Build(); mReactRootView.StartReactApplication(mReactInstanceManager, "MyReactNativeApp", null); SetContentView(mReactRootView); } protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { if (requestCode == OVERLAY_PERMISSION_REQ_CODE) { if (Build.VERSION.SdkInt >= BuildVersionCodes.M) { if (!Settings.CanDrawOverlays(this)) { // SYSTEM_ALERT_WINDOW permission not granted... } } } } protected override void OnPause() { base.OnPause(); if (mReactInstanceManager != null) { mReactInstanceManager.OnHostPause(this); } } protected override void OnResume() { base.OnResume(); if (mReactInstanceManager != null) { mReactInstanceManager.OnHostResume(this, this); } } protected override void OnDestroy() { base.OnDestroy(); if (mReactInstanceManager != null) { mReactInstanceManager.OnHostDestroy(this); } } public override void OnBackPressed() { if (mReactInstanceManager != null) { mReactInstanceManager.OnBackPressed(); } else { base.OnBackPressed(); } } public void InvokeDefaultOnBackPressed() { base.OnBackPressed(); } public override bool OnKeyUp(Keycode keyCode, KeyEvent e) { if (keyCode == Keycode.Menu && mReactInstanceManager != null) { mReactInstanceManager.ShowDevOptionsDialog(); return true; } return base.OnKeyUp(keyCode, e); } } }
index.js
import React from 'react'; import { AppRegistry, Platform, StyleSheet, Text, Button, View,NativeModules } from 'react-native'; console.log(NativeModules); const instructions = Platform.select({ ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu', android: 'Double tap R on your keyboard to reload this is part of React,\n' + 'Shake or press menu button for dev menu', }); const {XNativeModule}=NativeModules; const RNHelloWorld=()=> { return ( <View style={styles.container}> <Text style={styles.welcome}> Hey there Judson! This is React native project </Text> <Text style={styles.instructions}> To get started, edit App.js </Text> <Text style={styles.instructions}> {instructions} </Text> <Button onPress={() => XNativeModule.Foo()} title="Call Native Module" /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, welcome: { fontSize: 20, textAlign: 'center', margin: 10, }, instructions: { textAlign: 'center', color: '#333333', marginBottom: 5, }, }); AppRegistry.registerComponent('MyReactNativeApp', () => RNHelloWorld);
错误信息
undefined is not an object (evaluating 'u.Foo')
修复建议
注册自定义NativePackage
这是核心问题:在MainActivity的ReactInstanceManager构建代码中,只添加了官方的MainReactPackage,但没有注册你自定义的NativePackage。需要在.AddPackage(new MainReactPackage())之后补充:.AddPackage(new NativePackage())只有注册后,React Native才能识别并加载你的
XNativeModule。清理冗余特性
Xamarin环境中,[ReactMethod]特性已经足够将方法暴露给JS端,[Export("Foo")]属于冗余配置,建议移除,避免潜在的JNI绑定冲突。验证模块名称一致性
确保NativeModule类的Name属性值"XNativeModule"和JS中NativeModules.XNativeModule的名称完全一致(大小写敏感),否则JS端无法找到对应模块。调试确认模块加载状态
可以在JS端打印全部原生模块列表,确认XNativeModule是否被正确加载:console.log('Loaded Native Modules:', NativeModules);如果输出中没有
XNativeModule,说明原生模块注册流程仍有问题,需要检查包注册代码和类的继承实现是否正确。
内容的提问来源于stack exchange,提问作者Judson Abraham
相关产品推荐
相关产品推荐

