DEV Community

İnanç Akduvan
İnanç Akduvan

Posted on

How I handle communication between React Native Webview and Web project

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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");
}
Enter fullscreen mode Exit fullscreen mode

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");
}
Enter fullscreen mode Exit fullscreen mode

Thank you for reading :)


My github profile:
https://github.com/inancakduvan

My twitter account:
https://twitter.com/InancAkduvan

Top comments (3)

Collapse
 
medicansz profile image
MedicansZ • Edited

origin part only work on simulator
on real device i alway got empty string but it do receive messages

Collapse
 
venkateshparihar profile image
venkateshparihar • Edited

@inancakduvan you have use document.addEventListener to listen the event. why you have not use window.addEventListener?

Collapse
 
inancakduvan profile image
İnanç Akduvan

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 🙏