3

I have an Android class that extends SimpleViewManager class and encapsulates a MapView. Setting props from React Native JavaScript class works like a charm (using the @ReactProp annotation). However, i'd like to be able to call a method on the view, something like the following:

public void centerToMyLocation(MapView view) {
    view.getController().setCenter(myLocation);
}

I've tried using the @ReactMethod annotation, getting a ref for the MapView in JavaScript and then call the centerToMyLocation method on that object. But it doesn't work (I get mapViewRef.centerToMyLocation is not a function error).

How can I call the method from a JavaScript class where I render the native MapView component?

Jan Kalfus
  • 5,422
  • 2
  • 30
  • 38

2 Answers2

11

Ok, the following worked for me:

  1. Add a ref to the native component in the render method of the JavaScript class.
  2. Use findNodeHandle method from react-native package, passing the obtained ref as an argument. The findNodeHandle method returns a react ID, save it.
  3. Use UIManager.dispatchViewManagerCommand method from react-native, passing the react ID as the first argument. Second argument is a command id. Third argument are additional arguments (can be null).
  4. Override receiveCommand method in your ViewManager native class, which exposes the component. In this method, handle the command.

Example JS:

componentDidMount() {
    this.mapViewHandle = findNodeHandle(this.mapViewRef);
}

center() {
    UIManager.dispatchViewManagerCommand(this.mapViewHandle, 0, null);
}

render() {
    return (
        <MapView
            ref={(mv) => this.mapViewRef = mv} />
    );
}

Example Java:

@Override
public void receiveCommand(MapView view, int commandId, @Nullable ReadableArray args) {
    super.receiveCommand(view, commandId, args);
    if (commandId == 0) {
        if (mMyLocation != null) {
            view.getController().setCenter(mMyLocation);
        }
    }
}
Jan Kalfus
  • 5,422
  • 2
  • 30
  • 38
2

Here's another way to do it:

You just have to create a sibling UI Native Module to accompany the UI Native Component as seen in this SO answer

That should be an easier and more future proof way to do it.

SudoPlz
  • 20,996
  • 12
  • 82
  • 123