Inter-communication between native modules on React Native
Tags: reactnative, swift, kotlin, java
Published: 2021-02-19 13:08:14

React Native apps can be extended by native modules.
While they are easy to use from JavaScript, doing so between native modules is not officially documented.
I have several own native modules and I wanted to call those methods from another native module in ObjC/Swift/Java/Kotlin, so that I can avoid writing duplicate code.
I've dug into the core of React Native to understand how to do that.

## iOS

### Understanding `RCTBridge`

`RCTBridge` is the class to communicate with the JavaScript app.
It provides several useful methods to work with other native modules:

```objc
/**
 * Retrieve a bridge module instance by name or class. Note that modules are
 * lazily instantiated, so calling these methods for the first time with a given
 * module name/class may cause the class to be synchronously instantiated,
 * potentially blocking both the calling thread and main thread for a short time.
 *
 * Note: This method does NOT lazily load the particular module if it's not yet loaded.
 */
- (id)moduleForName:(NSString *)moduleName;
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad;
// Note: This method lazily load the module as necessary.
- (id)moduleForClass:(Class)moduleClass;
```

You can get an instance of a module with these methods.

### Get an `RCTBridge` instance

In your bridge module, you have to add a property for `RCTBridge` like so:

```objc
@interface YourModule : NSObject <RCTBridgeModule>

@property (nonatomic, weak) RCTBridge *bridge;

@end

@implementation YourModule

@synthesize bridge = _bridge;

@end
```

That's it.
The `bridge` property is automatically set when your module is initialized.

### Get another native module instance

For example, you can get an instance of `RCTUIManager` like so:

```objc
#import <React/RCTUIManager.h>

RCTUIManager* uiManager = [self.bridge moduleForClass:[RCTUIManager class]];
```

or, you can get it by name:

```objc
#import <React/RCTUIManager.h>

RCTUIManager* uiManager = [self.bridge moduleForName:@"RCTUIManager"];
```

## Android

### Understanding `ReactContext`

`ReactContext` class is similar to `RCTBridge` in iOS.
It provides a handy method to work with other native modules like so:

```java
  /** @return the instance of the specified module interface associated with this ReactContext. */
  public <T extends NativeModule> T getNativeModule(Class<T> nativeModuleInterface)
```

It allows you to get an instance of a native module by class.

### Get an instance of `ReactContext`

In your bridge module, your code should already look like:

```java
public class YourModule extends ReactContextBaseJavaModule {
    private final ReactApplicationContext reactContext;

    public AttachmentProcessorModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext = reactContext;
    }
```

So, you can quickly access via `this.reactContext`.

### Get another native module instance

For example, you can get an instance of `UIManagerModule` like so:

```java
import com.facebook.react.uimanager.UIManagerModule;

UIManagerModule uiManagerModule = this.reactContext.getNativeModule(UIManagerModule.class);
```

Now you can call methods of other modules.
Hope it helps.

* * *

- Follow me on [Twitter](https://twitter.com/inkdrop_app) & [Instagram](https://instagram.com/craftzdog)
- [Inkdrop — Markdown note-taking app](https://www.inkdrop.app/)
- [Solo developer's Discord community](https://discord.gg/S7hDmvh)

[![Subscribe Newsletter](https://miro.medium.com/proxy/1*-J5tp1_lulY9QknoLEv6zA.png)](http://eepurl.com/dNgJo6)

[![My YouTube channel](https://miro.medium.com/proxy/1*r-daItizHpAU-fQZk3ISag.png)](https://www.youtube.com/c/devaslife)