インデックス
- はじめに
- 一番シンプルな解決方法
- かなり回りくどい解決方法(変わった人向け)
- 感想
はじめに
モバイル版とPC版のどちらでも使うことのできる、「リンクを押下したときに別タブで1個だけ開いて、もう一つ開こうとしたら開いた方のタブにフォーカスする」メソッドについて、2通りの方法を紹介する。達成したい要件としては以下の通りである。
- リンクが貼られているウェブサイトAがあると仮定する
- 特にタブがない時にそのリンクを押下すると、別のタブBが開かれる
- タブBが開かれている時にウェブサイトAからリンクを押下すると、タブBにフォーカスする
インデックス2の方法を用いるのが一番簡単かつ最適解なのだが、インデックス3のパターンもどこかで使われるかもしれないので、一応書いておく。
また、次のような構造をしていると仮定する。
......(中略)
┣ hogepage/
┣ App.tsx
......(中略)
┣ pages/
┣ link/
┣ hogepageLink.tsx
......(中略)
一番シンプルな解決方法
通常は、以下のように設定すれば問題はない。
App.tsx
......(中略)
type AppProps = {
onClick: () => void;
};
const App = React.FC<AppProps> = ({ onClick, ...props }) => {
......(中略)
return (
<div { ...props }>
......(中略)
<HogepageLink target="hogehoge" onClick={onClick}>HogeHoge<HogepageLink />
......(中略)
</div>
)
};
HogepageLink.tsx
......(中略)
type HogepageLinkProps = StylableProps &
Omit<LinkProps, 'to'> & {
children: React.ReactNode;
};
const HogepageLink: React.FC<HogepageLinkProps> = ({
className,
children,
...props
}) => (
<Link to="/hogepage" className={className} {...props}>
{children}
</Link>
);
export default styled(HogepageLink)``;
結論から言えば、この方法を取れば間違いない。/hogepage
のハードコードはよろしくないが、あくまで構造を簡潔に書いておきたい感じなので、その点は一旦目を瞑っていただきたい。
かなり回りくどい解決方法(変わった人向け)
「一番シンプルな解決方法」からかなり遠ざかっているが、一応これでも動作する。ただし、めちゃくちゃ見づらい。メリットがあるとすれば、target
をつけ忘れても機能するという事ではあるが、onClick
を指定しようものならこれは機能しなくなるので要注意である。
App.tsx
......(中略)
const App = React.FC = ({ ...props }) => {
......(中略)
return (
<div { ...props }>
......(中略)
<HogepageLink>HogeHoge<HogepageLink />
......(中略)
</div>
)
};
hogepageLink.tsx
......(中略)
type HogepageLinkProps = StylableProps &
Omit<LinkProps, 'to'> & {
children: React.ReactNode;
};
const HogepageLink: React.FC<HogepageLinkProps> = ({
className,
children,
...props
}) => {
// 無限に新しいタブを開きたくないので、1つ対象のタブが開かれていたらそれにフォーカス
// 独自にクリックイベントを作っているのでonClickに値を挿入してはいけない
const hogepageURL = "/hogepage";
const tabName = 'hogepageTab';
const handleClick = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
e.preventDefault();
const openedTab = window.open('', tabName);
if (openedTab && !openedTab.closed) {
openedTab.location.href = hogepageURL;
openedTab.focus();
} else {
const newTab = window.open(hogepageURL, tabName);
if (newTab) {
newTab.name = tabName;
}
}
};
return (
<a
href={hogepageURL}
className={className}
onClick={handleClick}
{...props}
>
{children}
</a>
);
};
export default styled(HogepageLink)``;
感想
最初は「かなり回りくどい解決方法」の方を採用してやり遂げた気分になっていたのに、よくコードを見渡してみると、「一番シンプルな解決方法」だけで解決してしまったので、なんとも言えない気分になったのを覚えている。仕様の確認は、非常に大事である。