react-native与webview的通信

本周第一次真正意义的上的使用RN和H5混合开发了分享邀请功能,邀请主页面采用h5,其余弹窗交互采用RN,所以最重要的就是如何实现RN 与webview的通信

1 webView如何向RN发送消息?

首先需要在webView中视图加载时注入JavaScript

const injectedJavascript = `(function() {
       window.postMessage = function(data) {
            window.ReactNativeWebView.postMessage(data);
       };
})()`;

<WebView
  injectedJavaScript={injectedJavascript}
/>

此段的意义是因为react-native-webview在v5.0.0是将webview到react-native的通信已被完全重写。react-native-webview不再使用window.postMessage,window.postMessage已更改为window.ReactNativeWebView.postMessage
所以为了继续使用window.postMessage,我们使用injectionJavascript属性来做到这一点;
然后再web端我们再使用window.postMessage发送信息

methods: {
    showInviteRule() {
      window.postMessage("showInviteRule");
    },
    showInvitetype() {
      window.postMessage("showInvitetype");
    },
    openShareDetail() {
      window.postMessage("openShareDetail");
    }
  }
};

2 RN如何接收 webView发送的信息?

event.nativeEvent.data就是web发送的消息,只支持string类型,通过不同的消息类型做出不同的处理

const onMessageAction = event => {
    switch (event.nativeEvent.data) {
        case 'showInviteRule':
            showRule();
            break;
        case 'showInvitetype':
            showShareGuide();
            break;
        case 'openShareDetail':
            navigation.navigate('InviteeList', { shareInfo: data.user });
            break;
        default:
            break;
    }
};

<WebView
  onMessage={onMessageAction}
/>

3 RN如何向 webView发送消息?

在视图加载完时,使用InjectJavaScript向web注入JS,它与InjectedJavaScript区别是InjectedJavaScript只能运行一次,通过注入此段js,将user字符对象发送给web端

const webview = useRef(null);

 <WebView
            ref={webview}
            onLoad={() => {
                const user = Tools.syncGetter('user', data);
                const InjectJavaScript = `receiveMessage('${JSON.stringify(user)}');true;`;
                webview.current.injectJavaScript(InjectJavaScript);
            }}
 />

4 webView如何接收RN端的消息?

在Vue构建时我们能够触发RN传递过来的JS,获取到user信息,再做出处理

created() {
    window.receiveMessage = data => {
      const user = JSON.parse(data);
      this.user = user;
      this.invitations_success_count = user.invitations_success_count;
      if (typeof this.user.invitation) {
        this.reward_total_amount = this.user.invitation.reward_total_amount;
      }
    };
  },
奇怪的坑!!!

如果在onMessage中只打印了整个event对象 在开启debug模式调试时一切正常,一旦在非调试模式环境下,onMessage只要触发就会造成整个页面卡死,崩溃闪退。

 onMessage={event => {
                    console.log('event :', event);
                }}
完整代码示例

1 RN

image.png

2 web端

采用的是vue


asd

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

赞赏支持
被以下专题收入,发现更多相似内容