[ReactNative]WebViewでアプリとWebで値をやりとりする。


WebViewを使いたいので調査
やりたいことはWebViewから値をもらって、それをアプリにわたす。
逆にアプリからWebView側に値を渡すということ。

コンポーネントの情報

公式:WebView

github

※バージョンとか注意..

App→webViewで値を渡す

①injectedJavaScriptでjsコードを渡す。
WebViewのpropsにinjectedJavaScriptがあり、これは文字列でJsのコードを渡すとweb側で実行してくれる。

以下 Googleを表示してフォームに文字列をセットするサンプル。


export default class Sample extends React.Component<Props, State> {
  message = "hello world"
  js = `
    const inputs = document.getElementsByName("q") 
    inputs[0].value = "${this.message}"
  `

  render() {
    return (

      <WebView
        source={{uri:'https://www.google.co.jp/'}}
        injectedJavaScript={this.js}
      ></WebView>

    )
  }

②postMessage()を使う
App->WebViewでもpostMessageはできそうだけど、こっちはなんか面倒くさそうなので割愛。jsコードを渡せればなWeb側で実行する関数を定義しておいてくれれば、それに引数を渡して実行できるしね

WebView→Appで値を渡す

HTML側で実行するpostMessage()の呼び出し方が変わっている。自分のreact-nativeのバージョンに合わせて変更。

//Web側で動かすスクリプト
window.postMessage('OK'); //0.59はこっちでうごく
window.ReactNativeWebView.postMessage("OK"); //最新はこっちみたい

さらに、iOSは上記の記述でよかったのだけど、アンドロイドで上記をinjectしたらonMessageが反応しなかった。
setTimeoutで囲ったらうまくいったので、最終的に動いたコードは以下のようになった。

//App側
  js= `
    setTimeout( function(){window.postMessage("ok") }, 0 )
  `

  onMessage = (event) => {
    const {data} = event.nativeEvent
    alert(data)
  }

  render() {
    return (
      <WebView
        source={{uri:'http://example.co.jp/'}}
        injectedJavaScript={this.js} 
        onMessage={this.onMessage}      
      />
    )
  }

これでWeb側のpostMessage()が実行されたときに、WebViewのonMessageに設定した処理が動く。

参考リンク