Hi! That is how I handle communication between React Native Webview and Web Project. I am open to suggestions for a better solution. ✌️
Note: Purpose is not to be a tutorial article. It is just to share the way I prefer, and get feedback for better opinions. Sorry for the mistakes.
Let's start by coding a React Component including a Webview.
1) Here is just a simple component which has Webview component and a back button
export default function App() {
return (
<div className="container">
<div className="backButton">Back</div>
<WebView
source={{ uri: 'https://your-web-project.com' }}
/>
</div>
);
}
2) Now we will send a message to our Web Project from React Native Webview
Our case is that:
Send a message to Web Project when back button is clicked.
export default function App() {
const [webviewRef, setWebviewRef] = useState(null);
// on back button click, send message with postMessage
const handleBackButton = () => {
webviewRef.postMessage("goBack");
}
return (
<div className="container">
<div
className="backButton"
onClick={() => handleBackButton()}
>Back</div>
// We might also send a message when webview loaded.
<WebView
ref={ref => setWebviewRef(ref)}
source={{ uri: 'https://your-web-project.com' }}
onLoadEnd={() => webviewRef.postMessage("webviewLoaded")}
/>
</div>
);
}
3) It is time to handle message in Web Project
Now we leave the React Native project aside. And we write code in our Web Project
// Listen messages received
document.addEventListener("message", (event) => {
const message = event.data;
handleMessages(message);
})
// Handle messages
function handleMessages(message) {
const messageCallbacks = {
"goBack": handleGoBackMessage,
"webviewLoaded": handleWebviewLoadedMessage
}
messageCallbacks[message]();
}
// Handle go back message
function handleGoBackMessage() {
window.history.back();
}
// Handle webview loaded message
function handleWebviewLoadedMessage() {
const body = document.querySelector("BODY");
body.setAttribute("data-environment", "webview");
}
EXTRA PART
4) We can check the origin of the message.
It may be better to check the origin of the message while handling. If not, it may causes problems in some cases, for example, if a message is receiving from a third party library, messages will conflict.
// Listen messages received
document.addEventListener("message", (event) => {
const origin = event.origin;
const message = event.data;
if(origin === "https://your-web-project.com") {
handleMessages(message);
}
})
// Handle messages
function handleMessages(message) {
const messageCallbacks = {
"goBack": handleGoBackMessage,
"webviewLoaded": handleWebviewLoadedMessage
}
messageCallbacks[message]();
}
// Handle go back message
function handleGoBackMessage() {
window.history.back();
}
// Handle webview loaded message
function handleWebviewLoadedMessage() {
const body = document.querySelector("BODY");
body.setAttribute("data-environment", "webview");
}
Thank you for reading :)
My github profile:
https://github.com/inancakduvan
My twitter account:
https://twitter.com/InancAkduvan
Top comments (3)
origin part only work on simulator
on real device i alway got empty string but it do receive messages
@inancakduvan you have use document.addEventListener to listen the event. why you have not use window.addEventListener?
Hi,
As I remember, for the message event, document.addEventListener works on ios while window.addEventListener works on android.
I am not sure about it but that is what I remember.
Maybe you can double-check it 🙏