LoginSignup
1
1

More than 3 years have passed since last update.

【ReactNative】WebViewを使って既存資産を使い回す

Posted at

はじめに

ReactNativeを使って既存Webサービスのアプリ版を開発している場合、一部のアプリ独自の機能(例えばプッシュ通知やカメラ)を除いては既存ソースを流用できる場合があります。
例でいうと、ユーザ情報画面は既存のWebのマイページをそのまま表示するとかです。
その場合、WebViewを使うことになると思います。
ReactNativeでいうところのWebViewreact-native-webviewを使うことになりますが、ここで問題になってくるのがReactNative側のコードとWebView側のコードの連携処理です。
先のマイページの例でいうと、WebView側のマイページ画面のソースコードにReactNative側からユーザ情報を渡してあげなければ成立しません。
今回はreact-native-webviewを導入した上で、WebViewとの値の受け渡し方法について調べました。

環境情報

"react-native": "0.61.5",
"react-native-webview": "^9.2.1",

インストール

react-native-webviewをインストールしていない場合はインストール。

yarn add  react-native-webview

WebViewに値を渡す

WebViewに値を渡す場合はinjectedJavaScriptを使います。
injectedJavaScriptには文字列型でJavascriptのコードを渡せます。

WebViewComponent.tsx
import React from 'react';
import { WebView } from 'react-native-webview';

// WebViewに渡すコード
const injectedCode : string = `
    function fireInjectedJavaScript(){
        alert('ReactNativeから渡されたコードを実行しました!');
    }
`;

// WebViewで表示させるHTML
const html : string = `
      <html>
      <head>
      </head>
      <body>
        <h1>Title</h1>
        <form name="test">
            <input type="button" value="injectedJavaScript" onClick="fireInjectedJavaScript()">
        </form>
      </body>
      </html>
`;

// ...割愛

render(
    <WebView source={{html : html}} injectedJavaScript={injectedCode} />
);

html中のボタンでfireInjectedJavascript()を実行していますが、これはReactNative側から渡された関数です。
よって、アプリで表示された場合のみ特定の処理を行うような作りにすることもできます。

渡したコードはWebViewが描画された後に実行されるため、jQuerydocument.getElementByIdなんかを使ってWebView側の特定のフォームの値や表示をいじることもできます(上記のマイページの例ではこの方法を使ってユーザ情報を渡す)。

WebViewから値を貰う

逆にWebView側から何らかのデータを受け取りたい場合はonMessageを使います。

WebViewComponent2.tsx
import React from 'react';
import { WebView, WebViewMessageEvent } from 'react-native-webview';

// WebViewで表示させるHTML
const html : string = `
      <html>
      <head>
        <script>
            // WebViewが読み込まれた時にデータを送信
            window.onload = function() {
                window.ReactNativeWebView.postMessage("onload")
            };

            // 定期的に実行(ポーリングなんかに使える??)
            setInterval(function () {
                window.ReactNativeWebView.postMessage({hoge : "setInterval"})
            }, 2000)

            // 特定の処理実行時にデータを送信
            function firePostMessage(){
                window.ReactNativeWebView.postMessage("button click")
            }
        </script>
      </head>
      <body>
        <h1>Title</h1>

        <form name="test">
            <input type="button" value="postMessage" onClick="firePostMessage()">
        </form>
      </body>
      </html>
`;

// ...割愛

// onMessage発火時処理
public onMessageFromHtml(event : WebViewMessageEvent) {
    console.log(event.nativeEvent.data);
}

render(
    <WebView source={{html : html}} onMessage={onMessageFromHtml} />
);

上記の例ではWebView読み込み時に実行と、定期的に実行、ボタンを押した時に実行、と3パターンを盛り込んでいます。
いずれの場合もwindow.ReactNativeWebView.postMessageを実行しており、ReactNative側ではWebViewMessageEvent型で受け取ります。
渡された値自体はWebViewMessageEventnativeEvent.dataの中に格納されています。
nativeEvent.datareactBaseSyntheticEventのジェネリクスとなっているため型は自由です(setIntervalのようにオブジェクトを渡すこともできます)。

おわりに

今回はreact-natiev-webviewをインストールし、ReactNativeWebView間でのデータの受け渡し方法を紹介しました。
既存のソースを使いまわせるので非常に有効な手ではないかと思います。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1