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 (
      
        
      
    );
  }
}

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 (
      
         (this.webref = r)}
          source={{
            uri:
              'https://github.com/react-native-community/react-native-webview',
          }}
        />
      
    );
  }
}

注意:

在IOS平台,RN端往Web端传递事件和数据时。

- 注入脚本的复合参数(如数组或JSON对象)应当使用JSON.stringify(data)进行处理,否则Web端无法接收到正确的参数。

RN端要调动Web端的一个方法,并传递复合参数:

let jsCode = `if(${callback}){
                 var func = ${callback};
                 func && func(${JSON.stringify(response.data)});
              }`;
webView.injectJavaScript(jsCode);

 

 

 

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 (
      
        
      
    );
  }
}

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

 

 

 

 

 

 

 

 

你可能感兴趣的:(React-Native)