🍣

【ReactNative】テキスト中のハイパーリンク対応

2020/11/06に公開

はじめに

普段ReactNativeのアプリを開発していますが、そこで少しハマった内容を紹介させていただきます。
画面上に<Text>で任意の文字列を表示させることができるのはReactNativeで開発されている方ならご存知かと思いますが、特にコンテンツをユーザが投稿して表示するタイプのアプリだと 「文章中のURLの箇所をハイパーリンク化させたい」 といったケースがあるかと思います。

App.tsx
import React from 'react';
import {SafeAreaView, Text, StatusBar} from 'react-native';

const App: () => React.ReactNode = () => {
  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView
        style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
        <Text>
          {`https://zenn.dev ←こんな感じの\n`}
          {`リンクの箇所をハイパーリンク化したい`}
        </Text>
      </SafeAreaView>
    </>
  );
};

export default App;

react-native-hyperlink1

調べた限りでは<Text>のプロパティだけでは「与えられた文字列の中からURLを判別してリンク化」することは不可能なようで、工夫が必要だと感じました。

環境情報

  • react@16.13.1
  • react-native@0.63.3

考えられる対処方法

ぱっと思いついたのは以下のような方法です。

  • ①与えられる文字列を解析して<TouchableOpacity>等で囲う
  • WebViewで表示してHTMLとして処理する
  • ③外部ライブラリを使う

①は文字通り、与えられた文字列を解析して"http://""https://"のようなリンクと思われる箇所を正規表現で抜き出して<TouchableOpacity>で囲う方法です。
動作はしそうですが、実装方法によっては描画パフォーマンスに影響しそうですし、何よりバグの温床になりかねないかなと思いました。

②は裏技っぽい上に、既存のデザインと差異がないようにHTML側のスタイルを考慮しないといけません。
※各端末サイズによる考慮も必要になってくるため管理が手間。

結局いくつかライブラリを調べて、使えそうなものを使うという③の方針で進めることにしました。

react-native-hyperlink

この手のライブラリで最もメジャーなのはreact-native-hyperlinkのようです。
まさにそのまんまの名前だったので非常に分かり易かったです。

インストール

yarn add react-native-hyperlink

実装

使い方も非常にシンプルでした。
冒頭に紹介したコードに適用する場合、まずreact-native-hyperlinkimportして、ハイパーリンク化したい要素をラップします。
その上で 「ハイパーリンクのスタイル」「タップ時のイベント」 を指定することで目的の処理を実装することができました。

App.tsx
import React from 'react';
import {SafeAreaView, Text, StatusBar} from 'react-native';
import Hyperlink from 'react-native-hyperlink';

const App: () => React.ReactNode = () => {
  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView
        style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
	{/** linkStyleでハイパーリンクのスタイルを指定 */}
	{/** onPressでタップ時の挙動を指定 */}	
        <Hyperlink
          linkStyle={{color: '#2980b9', fontWeight: 'bold'}}
          onPress={(url: string, text: string) => {
            console.log(url);
          }}>
          <Text>
            {`https://zenn.dev ←こんな感じの\n`}
            {`リンクの箇所をハイパーリンク化したい`}
          </Text>
        </Hyperlink>
      </SafeAreaView>
    </>
  );
};
export default App;

react-native-hyperlink2

下記はタップ時のコンソールです。リンク部分をタップすることで、リンクのみが引数としてイベントに渡されていることが確認できます。

https://zenn.dev

まとめ

今回は<Text>中に含まれているリンクについてreact-native-hyperlinkを使った処理方法をご紹介しました。
他にもいくつかパラメータがあり 「長押し時イベント」「タップした時のリンクの整形」 を行えるようなので、リンク周りの要件には一通り対応できるのではないかと思います。

ここで紹介した以外で有益な方法等ありましたら、コメントにて共有をお願いいたします。

Discussion