React-Native之WebView组件 - Native与Web的通信和交互

  • 时间:
  • 来源:互联网

文档地址:https://github.com/react-native-community/react-native-webview/blob/master/docs/Guide.md#communicating-between-js-and-native

 

WebView组件是RN端与Web端交互的一个常用组件。

原本WebView组件是放在react-native组件库当中的,现在RN把它从组件库当中移除了,放到了react-native-webview库当中。最近我在升级公司RN项目的app,在适配WebView组件当中遇到很多问题,特此记录一下,避免再次踩坑。

 

 

RN端与Web端的通信和交互方式有三种:

(1)React Native -> Web: The injectedJavaScript prop

(2)React Native -> Web: The injectJavaScript method

(3)Web -> React Native: The postMessage method and onMessage prop

React Native -> Web

1 The injectedJavaScript prop

- RN端注入JS脚本到Web端。

- 这是一个脚本,该脚本在首次加载网页后立即运行。

- 即使页面重新加载或导航离开,它也只能运行一次。

import React, { Component } from 'react';
import { View } from 'react-native';
import { WebView } from 'react-native-webview';

export default class App extends Component {
  render() {
    const runFirst = `
      document.body.style.backgroundColor = 'red';
      setTimeout(function() { window.alert('hi') }, 2000);
      true; // note: this is required, or you'll sometimes get silent failures
    `;
    return (
      <View style={{ flex: 1 }}>
        <WebView
          source={{
            uri:
              'https://github.com/react-native-community/react-native-webview',
          }}
          injectedJavaScript={runFirst}
        />
      </View>
    );
  }
}

2 The injectJavaScript method

- RN端注入JS脚本到Web端。

- 前面提到的injectedJavaScript道具的缺点是只能运行一次。

- 这就是为什么我们还在webview ref上公开了一个称为injectJavaScript的方法(请注意稍有不同的名称!)。

import React, { Component } from 'react';
import { View } from 'react-native';
import { WebView } from 'react-native-webview';

export default class App extends Component {
  render() {
    const run = `
      document.body.style.backgroundColor = 'blue';
      true;
    `;

    setTimeout(() => {
      this.webref.injectJavaScript(run);
    }, 3000);

    return (
      <View style={{ flex: 1 }}>
        <WebView
          ref={r => (this.webref = r)}
          source={{
            uri:
              'https://github.com/react-native-community/react-native-webview',
          }}
        />
      </View>
    );
  }
}

3 The injectedJavaScriptBeforeContentLoaded prop

- RN端注入JS脚本到Web端。

- 这是在首次加载网页之前运行的脚本。

- 即使页面重新加载或导航离开,它也只能运行一次。 如果要在执行Web代码之前将任何内容注入到窗口,本地存储或文档中,这将很有用。

import React, { Component } from 'react';
import { View } from 'react-native';
import { WebView } from 'react-native-webview';

export default class App extends Component {
  render() {
    const runFirst = `
      window.isNativeApp = true;
      true; // note: this is required, or you'll sometimes get silent failures
    `;
    return (
      <View style={{ flex: 1 }}>
        <WebView
          source={{
            uri:
              'https://github.com/react-native-community/react-native-webview',
          }}
          injectedJavaScriptBeforeContentLoaded={runFirst}
        />
      </View>
    );
  }
}

Web -> React Native

The window.ReactNativeWebView.postMessage method and onMessage prop

- Web端往RN传递事件和数据可以通过window.ReactNativeWebView.postMessage(params)方法和WebView组件的onMessage属性来实现。

- Web端调用window.ReactNativeWebView.postMessage(params)方法,携带一个字符串参数,往RN传递数据。

- RN端通过onMessage来监听Web传递的事件和数据,然后进行处理。

- 我们必须设置onMessage或window.ReactNativeWebView.postMessage方法。

- window.ReactNativeWebView.postMessage仅接受一个参数,该参数必须是字符串。

 

注意:

react-native-webview库5.0.0版本之前,Web端是用window.postMessage(param)方法往RN端传递事件和数据的。

5.0.0版本后,就改成了 window.ReactNativeWebView.postMessage(param)。

如果想要在新版本兼容旧版本的web端代码,可以注入JS代码中加入下列代码:

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

详情请参阅文档:https://github.com/react-native-community/react-native-webview/releases/tag/v5.0.0

 

 

 

 

 

举世武双
发布了54 篇原创文章 · 获赞 22 · 访问量 3万+
私信 关注

本文链接http://element-ui.cn/news/show-1442.aspx