公開日: 2021-08-06
更新日: 2021-08-07
react-linkifiyはテキスト内のリンクを解析し、有効なリンクに変換してくれるライブラリです。
解析したいテキストをLinkifyで囲みます。
<Linkify>
See source code at https://github.com/tasti/react-linkify/.
</Linkify>たったこれだけでhttps://github.com/tasti/react-linkify/がリンクに変換されます。
デフォルトの状態だと解析されたリンクは全てaタグで囲まれたリンクに変換されますが、それがサイト内のリンクでも遷移時にページがリロードされてしまいます。
これだとあまり良くないUXになってしまうため、サイト内のリンクをaタグの代わりにReact RouterのLinkでリンクを出力したくなりました。
// CustomLinkify.js
import React from 'react';
import { Link } from 'react-router-dom';
import Linkify from 'react-linkify';
// content: string (解析するテキスト)
const CustomLinkify = ({ content }) => {
const url = 'https://example.com';
// サイト内のリンクかどうか判定
const componentDecorator = (href, text, key) =>
!text.indexOf(url) ? (
<Link key={key} to={text.replace(url, '')}>
{text}
</Link>
) : (
<a key={key} href={href} target="_blank" rel="noopener noreferrer">
{text}
</a>
);
return <Linkify componentDecorator={componentDecorator}>{content}</Linkify>;
};
export default CustomLinkify;今回はCustomLinkifyという名前でコンポーネントを作成してみました。
<CustomLinkify content={content} />componentDecorator関数の中を見ていきます。
!text.indexOf(url)この条件式はtextがurlと前方一致(text.indexOf(url) === 0)の場合のみtrueになります。
参考にした記事はこちらです。
https://qiita.com/aqril_1132/items/9f69575bfbcf24bdf7b5
例えばhttps://example.com/やhttps://example.com/user1のような文字列はtrueになります。
<Link key={key} to={text.replace(url, '')}>
{text}
</Link>あとはLinkのpath指定で不要なURLの部分を削除します。
(例: https://example.com/user1 -> /user1)
<a key={key} href={href} target="_blank" rel="noopener noreferrer">
{text}
</a>aタグはこんな感じです。Reactでtarget="_blank"を指定する場合はrel="noopener noreferrer"も一緒に書かないと警告が出ます。
以上でサイト内のリンク(urlと前方一致のリンク)のみをLinkで出力できました。
何か間違っている記述等あればご指摘いただけると嬉しいです。Linkifyをカスタマイズする方法についてはこちらを参考にしました。
https://github.com/tasti/react-linkify/pull/51#issuecomment-355787057