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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 00:47:54