How to use PostMessage in a React Native webview?

Viewed 9376

I'm trying to use the postmessage to a page opened in a webview inside a React Native App. I tried many times, but still wasn't able to send it.

I can listen to messages from the webpage normally. I just can't send anything back.

I'm currently using react-native-webview 11.6.5

export default function WebPage() {
  const webviewRef = useRef();

  const onMessage = (event) => {
    //receive message from the web page. working here until here
    const data = JSON.parse(event.nativeEvent.data);

    //reply the message
    webviewRef.current.postMessage(
      JSON.stringify({reply: 'reply'}),
      '*'
    )
  }

  return <View>
    <WebView
      ref={webviewRef}
      originWhitelist={['*']}
      source={{ uri: 'https://robertnyman.com/html5/postMessage/postMessage.html' }}
      domStorageEnabled
      javaScriptEnabled
      onMessage={onMessage}
    />
  </View>


}

Any ideas what am I doing wrong?

UPDATE:

Thanks to @Ahmed Gaber help I was able to find this issue https://github.com/react-native-webview/react-native-webview/issues/809 and discover they're changing postMessage to injectJavaScript.

So I updated my code onMessage to the following:

const onMessage = (event) => {
  const data = JSON.parse(event.nativeEvent.data);

  //reply the message
  webviewRef.current.injectJavaScript(
    `window.postMessage(
      {
        reply: 'reply'
      }
    );`
  )
}
2 Answers

to send data from app to webview use injectedJavaScript
to send data from webview to app use postMessage
to recieve data data in webview that send by postMessage use onMessage

//this Js function will be injected into the web page after the document finishes loading.
//this function will Post a message to WebView.
const INJECTED_JAVASCRIPT = `(function() {
    window.ReactNativeWebView.postMessage(JSON.stringify({key : "value"}));
})();`;



<WebView
  source={{ uri: 'https://reactnative.dev' }}
  injectedJavaScript={INJECTED_JAVASCRIPT}
  onMessage={(event) => {
       const data = JSON.parse(event.nativeEvent.data);
       alert(data.key);
  }}
/>;

React native code

    function getInjectableJSMessage(message) {
        return `
          (function() {
            document.dispatchEvent(new MessageEvent('message', {
              data: ${JSON.stringify(message)}
            }));
          })();
        `;
      }
function sendDataToWebView() {
    webviewRef.current?.injectJavaScript(
      getInjectableJSMessage("Hello")
    );
  }

React web app code

React.useEffect(() => {
    function handleEvent(message) {
      console.log(message.data);
    }
    document.addEventListener("message", handleEvent);

    return () =>
      document.removeEventListener("message", handleEvent);
  }, []);
Related