英文:
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");
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
<Button onPress={() => XNativeModule.Foo()} title="Call Native Module" />
答案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("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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论