How to communicate with data between WebViews in React Native

Introduction

In this shot, we will learn how to send data from WebView to a React Native app and vice versa.

Installation

First, go to the terminal and create a react-native application.

npx react-native init webviewdata
cd webviewdata

Now, install the react-native-webview package.

npm i react-native-webview

How to send data from WebView to a React Native app

Now, we are going to allow the WebView page to send a response back to the React Native app. This is particularly useful if your React Native application has to deal with certain logic where your website or webpage has to send data to your React Native app.

Import the React Native WebView package in App.js. We will create a normal HTML page in WebView and use “script” tags to let the HTML page communicate with the React Native app.

In the “script” tag, we are going to call a sendDataToReactNativeApp() function in which we will use a window property called window.ReactNativeWebView.postMessage("Message or Data We need to Send"). This function will be called when the user clicks on the button.

Once this button is clicked, we need to capture the particular event in React Native with the onMessage prop in the WebView Component.

We define a function called onMessage and attach this particular function to the WebView prop.

function onMessage(data) {
    alert(data.nativeEvent.data);
  }

In the WebView Component:


 <WebView
        scalesPageToFit={false}
        mixedContentMode="compatibility"
        onMessage={onMessage}
        source={{html:'' }}
/>

In the source prop, use HTML tags or your own website with the logic you need to implement in your React Native app.

Our App.js code will look as follows:

import React from 'react';
import {SafeAreaView, ScrollView, StyleSheet, Text, View} from 'react-native';
import {WebView} from 'react-native-webview';
const App = () => {
function onMessage(data) {
alert(data.nativeEvent.data);
}
return (
<SafeAreaView style={{flex: 1}}>
<WebView
scalesPageToFit={false}
mixedContentMode="compatibility"
onMessage={onMessage}
source={{
html: `
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body
style="
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
"
>
<button
onclick="sendDataToReactNativeApp()"
style="
padding: 20;
width: 200;
font-size: 20;
color: white;
background-color: #6751ff;
"
>
Send Data To React Native App
</button>
<script>
const sendDataToReactNativeApp = async () => {
window.ReactNativeWebView.postMessage('Data from WebView / Website');
};
</script>
</body>
</html>
`,
}}
/>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
},
highlight: {
fontWeight: '700',
},
});
export default App;

How to send data from a React Native app to WebView

Now, let’s send data from a React Native app to WebView. Create a function called webviewRef and attach it to the WebView component.

Next, create a function called sendDataToWebView and add the code below to it.

function sendDataToWebView() {
    webviewRef.current.postMessage('Data from React Native App');
  }

Inside the “script” tag, use window.addEventListener to listen to the event from the React Native app.

  window.addEventListener("message", message => {
                alert(message.data) 
              });

Now, App.js will look as follows:

import React, {useRef} from 'react';
import {
SafeAreaView,
StyleSheet,
Text,
View,
TouchableOpacity,
} from 'react-native';
import {WebView} from 'react-native-webview';
const App = () => {
function onMessage(data) {
alert(data.nativeEvent.data);
}
function sendDataToWebView() {
webviewRef.current.postMessage('Data from React Native App');
}
const webviewRef = useRef();
return (
<SafeAreaView style={{flex: 1}}>
<View style={{alignItems: 'center'}}>
<TouchableOpacity
onPress={() => sendDataToWebView()}
style={{
padding: 20,
width: 300,
marginTop: 100,
backgroundColor: '#6751ff',
alignItems: 'center',
}}>
<Text style={{fontSize: 20, color: 'white'}}>
Send Data To WebView / Website
</Text>
</TouchableOpacity>
</View>
<WebView
ref={webviewRef}
scalesPageToFit={false}
mixedContentMode="compatibility"
onMessage={onMessage}
source={{
html: `
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body
style="
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
"
>
<button
onclick="sendDataToReactNativeApp()"
style="
padding: 20;
width: 200;
font-size: 20;
color: white;
background-color: #6751ff;
"
>
Send Data To React Native App
</button>
<script>
const sendDataToReactNativeApp = async () => {
window.ReactNativeWebView.postMessage('Data from WebView / Website');
};
window.addEventListener("message", message => {
alert(message.data)
});
</script>
</body>
</html>
`,
}}
/>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
},
highlight: {
fontWeight: '700',
},
});
export default App;

To test the app, run npm run android.

Conclusion

In this shot, we discuss how to send data from WebView to a React Native app and from a React Native app to WebView.

All the code from this shot can be found on GitHub.