Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Request] Invoke Methods of Native UI Components #2272

Closed
Hybrid-Force opened this issue Aug 8, 2015 · 12 comments
Closed

[Request] Invoke Methods of Native UI Components #2272

Hybrid-Force opened this issue Aug 8, 2015 · 12 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@Hybrid-Force
Copy link

In React Native, we can expose properties of native UI components and native UI components can send events to JS. However, it lack the ability to invoke methods of native UI components.

For example, I have a drawing pad which is a custom native UI component. I want to be able to call some method from JS side and let the native drawing pad export the image.

I have been hacking around RCTUIManager which has the viewRegistry and viewManagerRegistry, and managed to invoked methods of native UI components via view manager.

I think calling native UI components' methods is common requirement and it would be nice to have it built in React Native

@alinz
Copy link

alinz commented Aug 10, 2015

If I understand correctly, You want to expose native react's methods to JS. I use category feature in objective-c to expose the methods. So if you really need some method to be exposed in your application just create a manager class and expose those methods.
You can take a look at this which does the same thing.

@Hybrid-Force
Copy link
Author

Thanks @alinz. I do know how to do that. I also used category to expose methods of native views :)

Thanks to the category feature of obj-c so that I can extend RCTUIManager without messing the code of the core modules. But, what if other languages (we will support Android, right?) do not have such similar feature as category? Then we might have to modify the code of react native core modules in order to expose methods of native ui components which I think is a quite common requirement.

What I am thinking is that, could we add some api to RCTUIManager (or some other better place) and provide some macro and documentation to make it easier to expose methods of native ui components? And also take this requirement into consideration when we build core modules for Android.

@nicklockwood
Copy link
Contributor

@Hybrid-Force The current way to expose methods of native views is via methods on the ViewManager which take the view's reactTag as the first argument. There's no need to modify the RCTUIManager for this.

If you want to expose methods on an existing view then you can use a category to add additional methods to its ViewManager, as @alinz suggests, but it's not the only way to do so.

An alternative solution would be to either add the methods directly to the view manager and open a pull request (if you think they'd be useful to others), or subclass the view manager and add your new methods, then either:

  1. Inject your new view manager module using the bridge moduleProvider or extraModules delegate method so that it overrides the standard component. Or
  2. Export your view manager module with a different name and then write a new JS wrapper for it so you can use it alongside the standard component.

@chirag04
Copy link
Contributor

@nicklockwood I like point 2 in alternative solution but what if js wrapper also needs inheritance.

For eg: I need onChange with Text component which wouldn't make sense for most usecases but it does for me. So I will subclass the RCTText and got it to work with a custom js wrapper. The js wrapper is just a copy paste of text.js with onChange handler added.

Now i get all these warning for using internal modules in the js wrapper. How do i handle this case?

@alinz
Copy link

alinz commented Aug 10, 2015

@nicklockwood would you provide the example for Inject your new view manager module using.... The reason I'm asking is I was trying to extend WebView component and I end up copying a lot of code to my module which was a nightmare if WebView component for next version changes. Thats why I ended up using category feature in objective-c.

@nicklockwood
Copy link
Contributor

@alinz

RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:jsBundle moduleProvider:^{
  return @[[[MyCustomWebViewManager alloc] init]];
} launchOptions: nil];

RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"MyApp"];

@Hybrid-Force
Copy link
Author

Thanks for the suggestion @nicklockwood. I re-read @alinz's example and found that this is exactly what I needed.

@chirag04
Copy link
Contributor

@nicklockwood Thoughts on my comment?

@nicklockwood
Copy link
Contributor

@chirag04 I'm not too sure about the rules for inheritance on the JS side. Maybe @vjeux can help?

@vjeux
Copy link
Contributor

vjeux commented Aug 13, 2015

This is a tricky one, we would need to expose all the internals that Text.js is using to implement itself. The big one that's not exposed right now is ReactNativeViewAttributes and I'm not sure that we want to expose it :( Sorry I don't have a good solution :x

@ssssssssssss
Copy link

What do you guys think of this one?
https://github.com/wix/react-native-invoke

@futurechallenger
Copy link

It's actually very easy. You can check out how Image in react-native did.

You export a UI component like:

const requireNativeComponent = require('requireNativeComponent');
const RCTImageView = requireNativeComponent('RCTImageView', Image)

And you can use the method in this UI manager like a normal native module like this:

const NativeModules = require('NativeModules');
const ImageViewManager = NativeModules.ImageViewManager;

//...
    getSize: function(
      uri: string,
      success: (width: number, height: number) => void,
      failure?: (error: any) => void,
    ) {
      ImageViewManager.getSize(
        uri,
        success,
        failure ||
          function() {
            console.warn('Failed to get size for image: ' + uri);
          },
      );
    },
//...

@facebook facebook locked as resolved and limited conversation to collaborators Jul 22, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

8 participants