DEV Community

Cover image for Communication between React Native web view and React app
Balamurugan
Balamurugan

Posted on

1

Communication between React Native web view and React app

This is one way of data communication between React native web view and react application.

There could me many possible ways for communicating between a react native app's web view and the react application that is hosted separately. I came across such requirement and I'm sharing the solution that I decided to apply here.

First of all, let's have a basic implementation of a react application and reatc native application.

A simple React application:-

  1. In useEffect() of App.js, add an event listener that listens for any native event. It is present within the "window" object of HTML. The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target. Ref: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
  2. In the listener function that we attach, we get the nativeEvent object, within which we can find the data that is being sent from React native or any external source that is targeted to the HTML document.
  3. To send the message to react native from react, we can use window.ReactNativeWebView.postMessage() method. This doesn't require any additional import or any package to be added. It comes in-built with "window" object of HTML. The window.postMessage() method safely enables cross-origin communication between Window objects; e.g., between a page and a pop-up that it spawned, or between a page and an iframe embedded within it.Ref: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
import React, {useEffect} from 'react';
const App = () => {
// listener to receive msgs from react native
useEffect(() => {
const messageListener = window.addEventListener('message', (nativeEvent) => {
conssole.log(nativeEvent?.data);
});
return messageListener;
}, []);
// method to send msg to react native
const sendMessage = () => {
window.ReactNativeWebView.postMessage('Hi from PWA');
};
return (
<div className="App">
<button onClick={sendMessage}>
{` Say Hi`}
</button>
</header>
</div>
);
}
export default App;
view raw App.js hosted with ❤ by GitHub

Image description

A simple react native application with web view:-

  1. Create a simple webview from any npm package
  2. To receive messages from the website, attach a method that points to the onMessage = {} property in the webview. In that function we can handle the incoming message.
  3. To send messages to react, we need to set ref to the web view to get the current instance of the referred object using useRef(). Attach it with ref = {webViewRef}
  4. Using webViewRef.current.postMessage(), we can send messages to react website.
  5. If we want to trigger something at the time of componentDidMount(), then we can do it by adding the required method at onLoadEnd() property of webview - that triggers a callback when the webview has loaded a website on it.
  6. We have mentioned the latest version of userAgents. Also had some props enables such as domStorageEnabled, cacheEnabled, javaScriptEnabled, etc for better performance of react native screen that loads webview.
  7. We can also show custom loaders until the site is loaded.
import { BackHandler, Dimensions, View } from 'react-native';
import React, { useEffect, useRef } from 'react';
import MyWebView from 'react-native-autoheight-webview';
const MyWebView = () => {
const webViewRef = useRef(null);
/**
* @function handleMessage
* @param {String} message
* @description this is the message from React PWA. Handle it here
*/
const handleMessage = (message = null) => {
// alert(JSON.stringify(message?.nativeEvent?.data));
};
/**
* @function sendMsgToPWA
* @description send any msg from React native app to PWA web
* @description this method will also be fired when the web view loaded succesfully - did mount 1st time - onLoad prop in <Webview>
*/
const sendMsgToPWA = () => {
if (webViewRef?.current) {
webViewRef?.current?.postMessage("Hi to React - from React native");
}
};
return (
<View style={[AppStyles.Flex1, AppStyles.AlignItemsCenter, AppStyles.JustifyContentCenter]}>
<MyWebView
ref={webViewRef} // Assign webview ref to the `webViewRef` while initial rendering
source={{ uri }}
style={{ width: Dimensions.get('window').width }}
renderLoading={() => <CustomLoader />}
mediaCapturePermissionGrantType="grant"
userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
startInLoadingState
javaScriptEnabled
domStorageEnabled
cacheEnabled
thirdPartyCookiesEnabled
allowsProtectedMedia
allowUniversalAccessFromFileURLs
allowsInlineMediaPlayback
mediaPlaybackRequiresUserAction={false}
onMessage={handleMessage}
onLoadEnd={sendMsgToPWA}
/>
</View>
);
};
export default MyWebView;
view raw MyWebView.js hosted with ❤ by GitHub

Image description

Sharing my Github repository here : https://github.com/svbala99/react-zoom and https://github.com/svbala99/zoomsdk-sign-generator-express

These repositories help you to setup a webview in which you can host a zoom meeting in web view in react native. The second repo is to generate secure signature. It is as dictated by official Zoom.

I hope this could be useful to somebody. Thanks for reading. Will come back with yet another interesting article. Stay healthy, take care!!!

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs