我正在开发一个 React Native 插件,其项目结构在
demos
目录中包含一个测试应用程序,用于测试插件功能。
当尝试处理从本机 Android 端发出的事件时,出现了我的问题。尽管在我的插件的 NativeEventEmitter
中设置了 index.js
,并为本机事件添加了监听器,但与该事件关联的回调似乎并未在 RN 端触发。
下面是我的插件中实现的简化版本
index.js
:
现在,在 demos 目录中的演示应用程序中,我能够成功侦听并处理相同的事件:
const { myLibrary } = NativeModules;
const EventEmitter = new NativeEventEmitter(myLibrary);
useEffect(() => {
const validationSuccessListener = myLibConnector.onValidationResultSuccess(handleValidationSuccess);
const validationFailureListener = myLibConnector.onValidationResultFailure(handleValidationFailure);
// This works as expected when added directly in the demo app
const eventListener = EventEmitter.addListener(
'onValidationResultSuccess',
validationResult => {
console.log('>> Received onValidationResultSuccess Event');
console.log('validationResult', validationResult);
}
);
return () => {
validationSuccessListener();
validationFailureListener();
eventListener.remove();
};
}, []);
// Initialization of the Listener
private final MappedValidationResultListener listener = new MappedValidationResultListener() {
@Override
public void onFailure(String result, Throwable error) {
handleError(EVENT_VALIDATION_FAILURE, result, error);
}
@Override
public void onResponse(Map<String, Object> response) {
WritableMap writableMap = RNUtil.toWritableMap(response);
handleSuccess(EVENT_VALIDATION_SUCCESS, writableMap);
}
};
//HELPER METHODS
private void handleSuccess(String eventName, WritableMap response){
sendEvent(reactContext,eventName, response);
}
private void handleError(String eventName, String result, Throwable error) {
WritableMap resMap = Arguments.createMap();
resMap.putString("result", result);
resMap.putMap("error", error != null ? errorToMap(error) : null);
sendEvent(reactContext,eventName, resMap.toString());
}
private void sendEvent(ReactContext reactContext, String eventName, Object params) {
if (reactContext.hasActiveReactInstance()) { // Ensure the context is active
Log.d("ReactNativeJS", "Event: " + eventName + ", params: " + params.toString());
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
} else {
Log.d("ReactNativeJS", "Skipping event: " + eventName + " (CatalystInstance not active)");
}
}
因此演示应用程序中的侦听器工作正常,但是当通过插件的index.js 使用相同的代码时,不会触发事件侦听器回调。我确信本机事件正在正确发出;然而,插件中的 React Native 端似乎存在一些错误配置。
有人遇到过类似的问题,或者可以深入了解插件设置中可能出现的问题吗?任何帮助将不胜感激!
我看到了类似的here,但不知道如何修复它。
我尝试在本机和 JS 端进行调试并记录输出,但插件端的发射器根本没有调用,即使我发送回 JS 端的最简单的数据也是如此。但当它在演示应用程序上时,效果很好
我想分享我遇到的这个问题的解决方案,其中本机发射器在开发 React Native 库时没有按预期触发事件。
在库和演示应用程序各有自己的
node_modules
的情况下,React Native 实例之间的差异可能会导致事件无法正确发出或接收。根本原因是,如果 NativeEventEmitter
是从与您的应用程序使用的不同的 react-native
实例创建的,则不会触发侦听器函数。
要解决此问题,请确保您的库和演示应用程序都使用同一
NativeEventEmitter
包中的 react-native
。在本地测试时,您可以在演示应用程序中修改导入语句,如下所示:
// Use this for testing locally in the demo app
import { NativeEventEmitter, NativeModules } from "demos/your-demo-app/node_modules/react-native";
代替:
// Avoid using this in your demo app for local tests
import { NativeEventEmitter, NativeModules } from "react-native";
请记住,此调整仅用于本地测试目的,不应包含在您的生产版本中。当您准备好发布库时,恢复到标准 React Native 导入。