How I handle communication between React Native Webview and Web project

İnanç Akduvan - Feb 11 '22 - - Dev Community

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

. . . . . . . . . . . .