如何修复React Native中的错误undefined is not an object (evaluating ‘u.Foo’)?

huangapple go评论76阅读模式
英文:

How to fix error undefined is not an object (evaluating 'u.Foo') in React Native?

问题

I'm working on an application which acts as a bridge between Xamarin and React Native. I'm following this GitHub project:

https://github.com/voydz/xamarin-react-native

This is my NativePackage.cs code:

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&quot);
            Toast.MakeText(ReactApplicationContext, "Hello Native World", ToastLength.Long).Show();
        }
    }
}

Following is my MainActivity code:

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
    {
        // ... (code continues)
    }
}

Following is my index.js code:

import React, { Component } 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=()=> {
 // ... (code continues)
}

// Module name
AppRegistry.registerComponent('MyReactNativeApp', () => RNHelloWorld);

I'm getting the following error when I click the button:

undefined is not an object (evaluating 'u.Foo')

Currently in my code when I call XNativeModule.Foo() from my JavaScript code, React Native bridges the call to the native module by sending a message to the native side using a message queue. On the native side, the Xamarin runtime receives the message and routes it to the appropriate native module. In this case, it will call the Foo() method defined in the XNativeModule class. In Xamarin.Android, the ReactContextBaseJavaModule class is used to create a native module that can be called from the React Native JavaScript code. But it is not working for me. I have no clue how to fix this. Any suggestions?

英文:

I'm working on an application which acts as a bridge between Xamarin and React Native. I'm following this GitHub project

https://github.com/voydz/xamarin-react-native

This is my NativePackage.cs code-

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();
        }
    }
}

Following is my MainActivity code

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);
        }
    }
}

Following is my index.js code

import React, { Component } 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,
  },
});

// Module name
AppRegistry.registerComponent('MyReactNativeApp', () => RNHelloWorld);

I'm getting following error when I click the button.

undefined is not an object (evaluating 'u.Foo')

Currently in my code when I call XNativeModule.Foo() from my JavaScript code, React Native bridges the call to the native module by sending a message to the native side using a message queue. On the native side, the Xamarin runtime receives the message and routes it to the appropriate native module. In this case, it will call the Foo() method defined in the XNativeModule class. In Xamarin.Android, the ReactContextBaseJavaModule class is used to create a native module that can be called from the React Native JavaScript code. But it is not working for me. I have no clue how to fix this. Any suggestions?

答案1

得分: 0

由于Foo不是一个类方法,你可以从按钮按下事件中移除this

<Button onPress={() => XNativeModule.Foo()} title="调用本地模块" />
英文:

Since Foo isn't a class method, can you remove this from button press

&lt;Button onPress={() =&gt; XNativeModule.Foo()} title=&quot;Call Native Module&quot; /&gt;

答案2

得分: 0

I fixed that by adding the NativePackage class in ReactInstanceManager. Native package class consists of Foo method since NativePackage class was not registered we where getting undefined error for Foo method. This is the my changes in MainActivity code

 mReactRootView = new ReactRootView(this);
            mReactInstanceManager = ReactInstanceManager.Builder()
                    .SetApplication(Application)
                    .SetBundleAssetName("index.android.bundle")
                    .SetJSMainModulePath("index")
                    .AddPackage(new MainReactPackage())
                    .AddPackage(new NativePackage()) 
#if DEBUG
                    .SetUseDeveloperSupport(true)
#else
                    .SetUseDeveloperSupport(false)
#endif
                    .SetInitialLifecycleState(LifecycleState.Resumed)
                    .Build();

As you can see AddPackage(new NativePackage()) in my MainActivity code. This fixed it and I was able to deploy the app without any exceptions.

英文:

I fixed that by adding the NativePackage class in ReactInstanceManager. Native package class consists of Foo method since NativePackage class was not registered we where getting undefined error for Foo method. This is the my changes in MainActivity code

 mReactRootView = new ReactRootView(this);
            mReactInstanceManager = ReactInstanceManager.Builder()
                    .SetApplication(Application)
                    .SetBundleAssetName(&quot;index.android.bundle&quot;)
                    .SetJSMainModulePath(&quot;index&quot;)
                    .AddPackage(new MainReactPackage())
                    .AddPackage(new NativePackage()) 
#if DEBUG
                    .SetUseDeveloperSupport(true)
#else
                    .SetUseDeveloperSupport(false)
#endif
                    .SetInitialLifecycleState(LifecycleState.Resumed)
                    .Build();

As you can see AddPackage(new NativePackage()) in my MainActivity code. This fixed it and I was able to deploy the app without any exceptions.

huangapple
  • 本文由 发表于 2023年4月4日 15:22:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75926547.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定