12

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'
      }
    );`
  )
}
Felipe César
  • 1,234
  • 2
  • 16
  • 34

2 Answers2

23

To send data from app to webview, use injectedJavaScript
To send data from webview to app, use postMessage
To receive data in webview sent 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);
  }}
/>;

GabLeRoux
  • 16,715
  • 16
  • 63
  • 81
Ahmed Gaber
  • 3,384
  • 2
  • 12
  • 18
  • 4
    hm... thank you so much for your help. Thanks to help I found out they're changing "postMessage" to "injectJavascript" and was able to solve it using `webviewRef.current.injectJavaScript(INJECTED_JAVASCRIPT)` – Felipe César Jul 12 '21 at 22:31
4

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);
  }, []);
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 28 '22 at 09:24
  • How do I give an answer 100 upvotes? because this really saved me a lot of time. Thank you – Proff Mushiana Mulweli May 17 '23 at 06:47