production.log

株式会社リブセンスでエンジニアをやっている星直史のブログです。

React Nativeにおいて、WebViewでhtml内のリンクをブラウザアプリで処理をする方法

概要

先日、Expoアプリで使うWebViewはreact-native-communityを使わなければ表示させることができないという記事を書きました、今回もWebViewネタ。
WebViewを使用するときは、大きく2つに分かれます。

  1. URLを指定する場合
  2. HTMLを記述する場合

WebViewはWebView内でタグを押下すると、そのWebView内で画面遷移をしてしまう仕様です。
そのため、
タグを押下時にブラウザで開いて欲しい場合はうまく意図した通りに動作しません。

今回はWebViewでhtml内のリンクをブラウザアプリで処理をする方法について書きます。

解決方法

onShouldStartLoadWithRequest propsを使用することです。
具体的には、この関数内でLinking.openURL("https://~~")とすると意図した挙動となります。

onShouldStartLoadWithRequest={(event)=>{
  if(event.url == "about:blank"){
    return true
  } else {
    Linking.openURL(event.url);
  }
}}

onShouldStartLoadWithRequestは初期ロード時にも呼ばれます。
そのため、2行目の「if(event.url == "about:blank"){」を記述することで、

  • 初期ロード時は何もしない
  • 何かしらのリンクが押された場合は、ブラウザアプリで開く

としています。

その他試したこと

当初はonNavigationStateChangeの使用を検討していました。
これは、WebViewのロードが開始または終了したときに呼び出される関数です。 この関数を使用した場合、AndroidとiOSでWebViewの挙動が若干異なるため、使用をやめました。
具体的には、リンク先が、.htmlの場合は意図した挙動になるのですが、.jpgなど、画像の場合は、WebView内で遷移もしてしまうし、Linkingも実行してしまうという挙動となりました。
これは、onShouldStartLoadWithRequestと処理がクロスオーバーしてしまうためだと思われます。
*1 this.webview.reload()this.webview.stopLoading()を駆使すればうまいこと制御できそうですが、処理が複雑になってしまうことや、onShouldStartLoadWithRequestを使用すれば問題ないため、こちらで実装することはやめました。

*1:未検証です