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
The
react-native
used is not the same path and cannot receive events.It is because
custom_ library
usesreact-native
ofcustom_library/node_modules/react-native
instead ofyour_app
ofyour_app/node_modules/react-native
.Modify
import xxx from 'react-native'
toimport xxx from 'your_app/node_modules/react-native'
incustom_ library
to receive events normally.Using the released
custom_ library
will not cause this problem. Expected: it will not installdevDependencies
defined inreact-native
.I also want to know why
react-native
with different paths can not receive events.