React Native - NativeEventEmitter - JSModule not listen to events

2.1k Views Asked by At

Im want to create a RN package (will publish on npm soon) that has a native side. Because of that i thought could be a good idea to put it in my node_modules dir, so i can test while develop, only android for now.

  • I create the module following the docs, with create-react-native-library, it create with typescript
  • Wrote the Java Module and Package
  • Wrote the JS side of my module

Only thing thats not working is to get events from native side in my module js side. But if i put the event NativeEventEmitter directly on my App.js (RN component) it works like a charm.

I need to do some abstractions on top of events, so i can expose a friendly api.

Every change i made in my module, i run yarn run bob build (comes from create-react-native-library), and then yarn run android on my testing project

Here is my package directory structure

.
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── android
│   ├── build
│   │   ├── generated
│   │   ├── intermediates
│   │   ├── outputs
│   │   └── tmp
│   ├── build.gradle
│   ├── gradle
│   │   └── wrapper
│   ├── gradlew
│   ├── gradlew.bat
│   ├── local.properties
│   └── src
│       └── main
├── babel.config.js
├── ios
│   ├── GpsState.h
│   ├── GpsState.m
│   └── GpsState.xcodeproj
│       ├── project.pbxproj
│       └── project.xcworkspace
├── lib // that is the build destination dir
│   ├── commonjs
│   │   ├── index.js
│   │   ├── index.js.map
│   │   ├── types.js
│   │   └── types.js.map
│   ├── module
│   │   ├── index.js
│   │   ├── index.js.map
│   │   ├── types.js
│   │   └── types.js.map
│   └── typescript
│       ├── __tests__
│       ├── index.d.ts
│       └── types.d.ts
├── package-lock.json
├── package.json
├── react-native-gps-state.podspec
├── scripts
│   └── bootstrap.js
├── src
│   ├── __tests__
│   │   └── index.test.tsx
│   ├── index.tsx
│   └── types.ts
├── tsconfig.build.json
├── tsconfig.json
└── yarn.lock

My Module package.json only relevants parts

{
  "main": "lib/commonjs/index",
  "module": "lib/module/index",
  "types": "lib/typescript/index.d.ts",
  "react-native": "src/index",
  "source": "src/index",
  ....
  "scripts": {
    "test": "jest",
    "typescript": "tsc --noEmit",
    "lint": "eslint \"**/*.{js,ts,tsx}\"",
    "prepare": "bob build",
    "release": "release-it",
    "example": "yarn --cwd example",
    "pods": "cd example && pod-install --quiet",
    "bootstrap": "yarn example && yarn && yarn pods"
  },
}

My index.tsx (js part of my package)

import { NativeModules, NativeEventEmitter } from 'react-native';

const emitter = new NativeEventEmitter(NativeModules.GpsState);
emitter.addListener('OnStatusChange', (response: any) => {
    // never reach here, seems theres no listeners attached
    console.log('jsmodule -> OnStatusChange -> received....', response);
});

const GPSState = {
 foo: ()=>NativeModules.GPSState.bar() //those call to native side are working well by the way
 debugEmitter: ()=>NativeModules.GPSState.debugEmitter()
}

export default GPSState

And finally, iam use MessageQueue too to guarantee events are being dispatched, and they are

 LOG  GPSState debugEmitter js -> native
 LOG  {"args": [], "method": "debugEmitter", "module": "GPSState", "type": 1}
 LOG  ----------------------------------------------------------------------------------------------------------------------------------------------
 LOG  RCTDeviceEventEmitter emit native -> js
 LOG  {"args": ["OnStatusChange", {"status": 99}], "method": "emit", "module": "RCTDeviceEventEmitter", "type": 0}
 LOG  ----------------------------------------------------------------------------------------------------------------------------------------------

One last note, the MessageQueue.spy not work on my js package too, only in my App.js (RN component)

For who want a closer look this is the repo

Yep, thats all folks

1

There are 1 best solutions below

1
On

The react-native used is not the same path and cannot receive events.

It is because custom_ library uses react-native of custom_library/node_modules/react-native instead of your_app of your_app/node_modules/react-native.

Modify import xxx from 'react-native'to import xxx from 'your_app/node_modules/react-native' in custom_ library to receive events normally.

Using the released custom_ library will not cause this problem. Expected: it will not install devDependencies defined in react-native.

I also want to know why react-native with different paths can not receive events.