How to Pass Data between Native and JavaScript using React Native Bridge

Mohita Prakash
JavaScript in Plain English
5 min readJun 5, 2021

--

I would say the facility of having a bridge between JavaScript and our Native code is one of the best flexibilities that the React Native framework is giving us. Most of the developers or teams may encounter a situation where one couldn’t find an apt npm module or where there won’t be enough time to create an npm module for the use cases. Here, the bridge implementation comes in handy.

If we want to use any Native APIs or any other SDK written in Native language in the React Native project, we can make use of the React Native bridge and implement it in the Native side and use the bridge between Native and JavaScript for bi-directional data flow.

As mentioned in official docs, there are many ways to pass data between two worlds. We will see the below 3 ways for the same.

1. Promise
2. Callbacks
3. Event Emitters

Here, I have chosen ConnectSDK as the native SDK to implement on the Native side (Android and iOS). Connect SDK is an open-source framework that connects your mobile apps with multiple media device platforms. We will implement some API on the Native side and send it to the JavaScript side and also, we will pass some data from the JavaScript side to the Native side.

Step 1

Create a React Native project with the help of the link below.

Remove the default code from App.js and add your own component or you can add the below code. I have added a simple screen with stack navigation. For that, you will have to install node module “@react-navigation/native” and “@react-navigation/stack”. For more details about react-navigation, please follow the below link.

https://reactnavigation.org/docs/getting-started/

Now, try running the app using npx react-native run-android in android and npx react-native run-ios for iOS.

Step 2

Integrate ConnectSDK ( You can skip this step if you are using some other SDKs)

Android

Add this line to your app build.gradle and Sync the Gradle

Add the necessary permissions.

We have to create two java files in the Android project. One is the native module class where we will write the methods that can communicate with the JavaScript side and another file is a React package where we will register this native module. Then this package will be added to ReactNativeHost in the MainApplication.java file.

Create ConnectSDKNative.java and ConnectSDKNativePackage.java under your android root package. You can name your modules based on the SDK you choose. Add the below lines of code in respective files.

All Java native modules in Android need to implement the getName() method. This method returns a string, which represents the name of the native module. The native module can then be accessed in JavaScript using its name. For example, the above code snippet getName() returns "ConnectSDKNative". You can replace this with your module name.

Add the package to MainApplication.java getPackages() list.

Add the below line in MainApplication.java for initiating the Device Discovery.

DiscoveryManager.init(getApplicationContext());

Now the ConnectSDK initial setup is completed.

Step 3

Setting up the JavaScript side

Now that we have our java and iOS native side integration completed, let’s do some UI addition on the JavaScript side. I’ll create a simple UI with a button to initiate the device discovery and a list to show the discovered items.

In the above patch, const { ConnectSDKNative } = NativeModules gives JavaScript access to the native module. Using this we can call the methods which we are going to write inside our native module.

Step 4

Implementing the native method and exposing it to JavaScript.

As explained earlier, we can use Promise, Callback, or event emitters based on our need for communicating between Java and JavaScript.

  1. First, we will see the case of Callbacks. Callbacks are used to pass data from Java to JavaScript for asynchronous methods. They can also be used to asynchronously execute JavaScript from the Native side. We can only have two callbacks in your function arguments- a successCallback and a failureCallback. In addition, the last argument to a native module method call, if it’s a function, is treated as the successCallback, and the second to last argument to a native module method call, if it’s a function, is treated as the failure callback. If there are any params to be sent from JS, we can add them before the Callbacks.

An important detail to note is that a native module method can only invoke one callback, one time. This means that you can either call a success callback or a failure callback, but not both, and each callback can only be invoked at most one time.

On the JavaScript side, we will write the code to invoke this method and receive its callbacks.

2. Now we will be using Promises. Promises can resolve and reject the method call based on success and failure. Reject method can have different params like error code, message, WriteableMap object.

This console log will print the message passed from the Java side using the Promise.

3. Event Emitter is our third option to transfer data between Java and JavaScript. In this case, we don’t have to create a ReactMethod and invoke it. From the Native side, we will be emitting events/signal which will be listened by the Javascript code which we have written in JS side. NativeEventEmitter given by React Native will help us to listen to these events. It is having an addlistener method where we will be specifying the event name and will catch the incoming data inside the function call. Whereas in the Java side, RCTNativeAppEventEmitter class helps to emit these events along with data. Another thing to note down in Android is that we can’t transfer Java data types directly to the JavaScript side. We need to wrap it in such a way that it will be understandable by Javascript. The react bridge is giving us the helper classes such as WriteableMap, WriteableArray, etc.

We have to convert the custom object to WriteableMap before adding it to the event emitting method. You can find the helper method in the GitHub link at the end of this article. Also if you want to refer to the entire project source code, you can go to the same GitHub link.

That’s all folks!! That was quite some coding, right? But trust me, it is really interesting once you get your hands on it. Currently, this is having Android integration only. I am working on the iOS Native code addition. Soon, I’ll add that too in this article.

If you feel this article was useful, please leave some claps. It will be a huge motivation for me to contribute more. Have fun coding!

More content at plainenglish.io

--

--

Mobile Application Engineer | Talks about tech, finance and fitness | Believes in simplicity | Day Dreamer