react-native-web-community / react-native-web-webview

React Native for Web implementation of RN's WebView
https://react-native-web-community.github.io/react-native-web-webview/storybook
MIT License
133 stars 48 forks source link

The onMessage prop is never triggered on react-native-web #55

Closed gfaraj closed 2 years ago

gfaraj commented 2 years ago

I'm using this package to bring feature parity to my web and native apps, but I can't seem to communicate back to react native from the website.

My usage is:

    const onMessage = useCallback((message: WebViewMessageEvent) => {
            const data = JSON.parse(message.nativeEvent.data);
            console.log('Getting a message from the game web view...');
            console.log(data);
        }, [foo]);

       return (<WebView 
                style={styles.webView}
                source={source}
                javaScriptEnabled
                domStorageEnabled
                ref={() => {}}
                onMessage={onMessage}
                mixedContentMode={'always'}
                onNavigationStateChange={onNavigationStateChange}
                cacheEnabled={false} />);

The website I'm loading within the webview/iframe does this:

        var payloadStr = JSON.stringify(payload);
        var target = window.ReactNativeWebView || window.parent || window;
        var postMessageFunction = target && target.postMessage;

        if (postMessageFunction) {
            postMessageFunction(payloadStr);
        } else {
            console.log('Did not find target to post message!');
        }

The native webview works fine through window.ReactNativeWebView.postMessage but for web window.ReactNativeWebView is not defined and so I had to figure out where to post the message. This still doesn't trigger my onMessage though.

Any ideas?

gfaraj commented 2 years ago

I managed to get it to work by modifying the above code to this:

        var payloadStr = JSON.stringify(payload);

        if (window.ReactNativeWebView) {
            window.ReactNativeWebView.postMessage(payloadStr);
        } else if (window.parent) {
            window.parent.postMessage(payloadStr, '*');
        } else {
            window.postMessage(payloadStr, '*');
        }

It works on both native and web. I think adding something about this to the documentation would be great. Thanks for making this!

Cogneter commented 2 years ago

I managed to get it to work by modifying the above code to this:

        var payloadStr = JSON.stringify(payload);

        if (window.ReactNativeWebView) {
            window.ReactNativeWebView.postMessage(payloadStr);
        } else if (window.parent) {
            window.parent.postMessage(payloadStr, '*');
        } else {
            window.postMessage(payloadStr, '*');
        }

It works on both native and web. I think adding something about this to the documentation would be great. Thanks for making this!

I had the same problem and your solution worked. Thanks!