Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react native html postMessage can not reach to WebView

I use React Native webview to show index.html, and HTML will post messge to the app. The app will then receive the message and write it to console. The problem is the app cannot receive messages, when postMessage is immediately run on head. I think it maybe related to HTML not finished loading. I then used a delay with setTimeout, and it worked.

Now I want to know:

  • Is there better way to solve this problem?
  • Why the delay 100 milliscond did not work, but delay 200 milliscond did?

I am using React Native version 0.39.0, and Node version 7.2.0.

Here is the code I have so far:

index.html

<head>
<title>Index</title>
<script type="text/javascript" src="index.js"></script>
<script type="text/javascript">
    // can not be received
    postMessage('send to react native from index inline, no delay', '*');

    // can not be received
    setTimeout(function(){
        postMessage('send to react native from index inline, delay 0 milliscond', '*')
    }, 0);

    // can received
    setTimeout(function(){
        postMessage('send to react native from index inline, delay 100 milliscond', '*')
    }, 100);

    onload = function() {
        // can not be received
        postMessage('send to react native from index inline after onload, no delay', '*')

        // can received
        setTimeout(function () {
            postMessage('send to react native from index inline after onload, delay 0 milliscond', '*')
        }, 0);
    };
</script>

index.js

// can not be received
postMessage('send to react native from index.js, no delay', '*');

// can not be received
setTimeout(function() {
    postMessage('send to react native from index.js, delay 100 milliscond', '*')
}, 100);

// can received
setTimeout(function() {
    postMessage('send to react native from index.js, delay 200 milliscond', '*')
}, 200);

React Native web_view_page.js

return (
        <WebView
            source={{uri: 'http://127.0.0.1:8000/index.html'}}
            onMessage={(event) => console.log('onMessage:', event.nativeEvent.data)}/>
    );

Chrome console log

2016-12-21 11:45:02.367 web_view.js:147 onMessage: send to react native from index inline after onload, delay 0 milliscond
2016-12-21 11:45:02.491 web_view.js:147 onMessage: send to react native from index inline, delay 100 milliscond
2016-12-21 11:45:02.628 web_view.js:147 onMessage: send to react native from index.js, delay 200 milliscond
like image 699
liupeixin Avatar asked Dec 21 '16 06:12

liupeixin


1 Answers

I'm sure you've found your answer by now, but in the event you have not or if other people are in need then check out https://github.com/facebook/react-native/issues/11594.

Basically, you need to wait for the postMessage to be present in the window before we can successfully post messages.

function onBridgeReady(cb) {
  if (window.postMessage.length !== 1) {
    setTimeout(function() {
      onBridgeReady(cb)
    }, 100);
  } else {
    cb();
  }
}

onBridgeReady(function() {
  window.postMessage('Bridge is ready and WebView can now successfully receive messages.');
});

Source: Andrei Barabas

like image 123
Seth Avatar answered Oct 12 '22 21:10

Seth