【问题标题】:How can I send a data to webview by clicking on react native button如何通过单击 react native 按钮将数据发送到 webview
【发布时间】:2019-09-09 20:40:34
【问题描述】:

我使用了 componentDidMount 方法,该方法将数据正确发送到 webview,但是当我单击特定的 react native 按钮时,我想发送数据 webview。

在此 webview 中显示本地 html 页面,在此我将数据发送到 webview 并且在 html 页面中的加载事件警告在此 componentdidmount 方法中由 react native 发送的数据已成功将数据发送到 webview html 页面但是当我在方法中尝试相同的代码时,this.input 是未定义的。

   export default class HtmlRender extends Component {

   //error:this.input is undefined
   sendData() {
         this.input.postMessage( data )
   }

// This Is working
 componentDidMount(){
         this.input.postMessage( data)
   }


 render(){
      return (
          <View style={styles.fullContainer}>
               <View style={styles.webviewBorder}  >

                  <WebView
                    ref={(input) => this.input = input}
                    source={{uri:'file:///android_asset/Page.html'}}
                   />
               </View>
           <View  >
                <Button  onPress={this.sendData}>
                   <Text>
                      Data
                   </Text>
               </Button>
            </View>
  </View  >

)}

【问题讨论】:

    标签: javascript react-native webview


    【解决方案1】:

    您可以使用注入的JavaScript 来做到这一点。只需在 const 中定义您的 html 页面源代码

    const htmlData = require('./page.html');
    

    并创建如下所示的方法

    injectedToHtml() {
        const myData = {planet: 'earth', galaxy: 'milkyway'};
        let injectedData = `document.getElementById('container').value = '${myData.planet+myData.galaxy}';`;
        return injectedData;
       }
    

    并在您的组件中像这样返回您的网络视图

    <WebView
        source={htmlData}
        javaScriptEnabled={true}
        injectedJavaScript={injectedToHtml()}
        style={{flex: 1}}
    />
    

    就是这样!如果您还有任何问题,请告诉我。

    你的 html 文件看起来像这样..

    <!DOCTYPE html>
    <html>
        <head>
          <style>
              #container {
                  width:100%;
                  height:100vh;
                  display: flex;
                  align-items:center;
                  justify-content: center;
              }
          </style>
        </head>
        <body>
            <div id="container"></div>
        </body>
    </html>
    

    【讨论】:

    • 这可以在按钮单击反应原生时可能吗?假设如果容器数据为空并且我单击反应原生按钮,这将在容器中添加数据
    • 是的,你可以做到。 @MilindModi
    • 让我为您制作世博小吃。完成后我会发送给您。
    • 只是一个简单的问题,如果我想在加载 webview 后更改变量数据怎么办。之后我们可以更改数据吗?
    【解决方案2】:

    这是一个简单的代码,您可以在单击按钮时将数据发送到 WebView。

    import React, { Component } from 'react';
    import { Text, View, TouchableHighlight } from 'react-native';
    import { WebView } from 'react-native-webview';
    
    export default class App extends Component {
      constructor(props) {
        super(props);
      }
    
      sendDataToWebView() {
        let injectedData = `document.getElementById("login_field").value = 'example@github.com';`;
        this.webView.injectJavaScript(injectedData);
      }
    
      render() {
        return (
          <View style={{ flex: 1, marginTop: 35 }}>
    
            <TouchableHighlight style={{ padding: 10, backgroundColor: 'gray', marginTop: 20 }} onPress={() => this.sendDataToWebView()}>
              <Text style={{ color: 'white' }}>Send Data To WebView from React Native</Text>
            </TouchableHighlight>
    
            <WebView
              style={{ flex: 1 }}
              source={{ uri: 'https://github.com/login' }}
              ref={(webView) => this.webView = webView}
    
            />
          </View>
        );
      }
    }
    

    【讨论】:

      【解决方案3】:

      总之

      Sending Data from Native(Webview) to Web App

      // Native
      this.webviewRef.postMessage('Wayne is coming!!!')
      
      // Web
      window.addEventListener("message", message => {
        console.log(message.data) // Wayne is coming!!!
      });
      

      Sending data from Web App to Native(Webview)

      // Web App
      <button onClick={() => {
        if(window.ReactNativeWebView) { // ensure window.ReactNativeWebView is there, otherwise, web app might crash if is not there
          window.ReactNativeWebView.postMessage('Wayne is coming again')
        }
      }}>
      </button>
      
      // Native App
      <WebView
        onMessage={(event) => {
          console.log(event.nativeEvent.data) // Client received data
        }}
        source={{ uri: 'https://your.domain.com' }}
      />
      

      完整示例 React Native 代码

      import React, { Component } from 'react';
      import { WebView } from 'react-native-webview';
      import { View, Button } from 'react-native';
      
      class App extends Component {
        constructor(props) {
          super(props)
          this.webviewRef = null;
        }
        render() {
          return (
            <>
              <View style={{ flex: 1, alignContent: 'center', justifyContent: 'center' }}>
                <Button
                  title="Press me"
                  onPress={() => {
                    this.webviewRef.postMessage('Wayne is coming!!!')
                  }}
                />
              </View>
              <WebView
                onMessage={ (event) => {
                  console.log(event.nativeEvent.data) // Client received data
                }}
                source={{ uri: 'https://your.domain.com' }}
                ref={ref => this.webviewRef = ref}
              />
            </>
          )
        }
      }
      

      网络应用

      // register an event listener
      window.addEventListener("message", message => {
        console.log(message.data) // Wayne is coming!!!
        window.ReactNativeWebView.postMessage('Client received data')
      });
      

      【讨论】:

        【解决方案4】:

        不幸的是,使用 postMessage() 方法将数据从 Native(Webview) 发送到 Web App 已被弃用,取而代之的是 injectJavaScript()

        /**
         *  This script dispatches new custom messaging event
         */
        function getInjectableJSMessage(message) {
          return `
            (function() {
              document.dispatchEvent(new MessageEvent('message', {
                data: ${JSON.stringify(message)}
              }));
            })();
          `;
        }
        
        // somewhere in your code
        this.webviewRef.injectJavaScript(
            getInjectableJSMessage({
              message: 'Triggered event',
              triggeredAt: new Date(),
            })
        );
        

        在你的 web 应用中,注册一个事件监听器

        function handleEvent(message) {
           console.log(message.data);
        }
        
        // This will only work for Android
        // https://stackoverflow.com/a/58118984
        document.addEventListener("message", handleEvent);
        

        查看相关issue

        【讨论】:

          【解决方案5】:

          从 React Native 向 Webview 发送数据

          反应原生代码

          constructor (props) { 
           super(props);
           this.state = {  }  
           this.webView = React.createRef();
          }
          
          sendDataToWebView = (dataObject) => {
            
           this.webView.injectJavaScript(`( function() { 
             document.dispatchEvent( new MessageEvent('message', { 
             data: ${JSON.stringify(dataObject)}, 
             origin : 'react-native' 
            })); })();` );
             
          }
          
          render() {
           return(
            <WebView
             source={{ ... }}
             containerStyle={{ ... }}
             ref={(webView) => this.webView = webView}
            />)
          }
          

          WebView 代码

          if(window.ReactNativeWebView) {
            window.addEventListener("message", this.webViewEventHandler); //android 
            document.addEventListener("message", this.webViewEventHandler); //ios
          } 
          
          webViewEventHandler = (event) => {
           if (event.origin == 'react-native'){
            console.log(event.data) //get dataObject
           }  
          }
          

          【讨论】:

            猜你喜欢
            • 2022-11-04
            • 1970-01-01
            • 1970-01-01
            • 2021-08-19
            • 1970-01-01
            • 1970-01-01
            • 2020-09-15
            • 2014-03-01
            • 1970-01-01
            相关资源
            最近更新 更多