The existing answer works great if you only need to support Android, but I found it didn't work when I was trying to integrate with iOS as well. I burnt quite a lot of time trying to wrangle this method into iOS, so I'll recommend what I came up with instead: using the UIManager
that comes with react-native.
React Native Component
// ComponentWithNativeFunctionality.js
import {UIManager, findNodeHandle} from 'react-native';
class ComponentWithNativeFunctionality extends React.Component {
const myRef = React.createRef();
functionToCall = () => {
UIManager.dispatchViewManagerCommand(
findNodeHandle(this.myRef.current),
"nameOfFunctionToCallInNativeLand",
[/* additional arguments */]
);
}
render() {
return <NativeComponentView ref={this.myRef} />
}
}
Android
// YourViewManager.java
public class YourViewManager extends SimpleViewManager<YourView> {
// ...
@Override
public void receiveCommand(@NonNull YourView view, String commandId, @Nullable ReadableArray args) {
super.receiveCommand(view, commandId, args);
switch (commandId) {
case "nameOfFunctionToCallInNativeLand":
view.nameOfFunctionToCallInNativeLand();
break;
}
}
}
}
iOS (with Swift)
- Add
#import "React/RCTUIManager.h"
to your Bridging-Header.h
// YourViewManager.m
@interface RCT_EXTERN_MODULE(YourViewManagerClass, RCTViewManager)
//...
RCT_EXTERN_METHOD(
nameOfFunctionToCallInNativeLand: (nonnull NSNumber *)node
)
@end
// YourViewManagerClass.swift
@objc(YourViewManagerClass)
class YourViewManagerClass: RCTViewManager {
@objc func nameOfFunctionToCallInNativeLand(_ node: NSNumber) -> Void {
DispatchQueue.main.async {
let component = self.bridge.uiManager.view(
forReactTag: node
) as! MisnapCameraView
component.nameOfFunctionToCallInNativeLand()
}
}
}
Another note: you can't pass in a Promise like you can with modules. You will have to pass in a unique ID generated in JS, and then once your action is done, fire an event to bubble back the result to JS with the ID attached to the event.
NativeModules.YourNativeModule
to get the method in js layer. It's really not cool! – Dibri