👯‍♂️ Next.jsでLinkもbuttonも同じコンポーネントにして使いたい

2020-11-19 #Development

Tailwind CSS を使っていたらリンクにもボタンにも大量のクラスを記述する事になるので、できれば同じような記述は一箇所に集めておきたい…

という理由があってボタンの形状のものはリンクでもボタンでも一箇所にまとめて記載できるようにしておきたかったので作ってみました。

Next.js は next/link を使うと a タグが入れ子になるので階層が変わってしまい悩ましいなと思ったのですが、どうやったら良いのかなと調べてみたところ、 React ではタグに直接スプレッド構文で {...props} みたいな感じで渡す事ができるんですね…こいつは便利。

import Link from "next/link";

const Button = (props) => {
  const className = "inline-flex justify-center whitespace-no-wrap rounded-md border px-4 py-2 text-sm leading-5 font-medium bg-white border-gray-300 text-gray-700 hover:text-gray-500 active:bg-gray-50 active:text-gray-800 transition ease-in-out duration-150 " + props.className;

  return (
    <>
      {props.onClick ? (
        <button {...props} type="button" className={className}>
          {props.children}
        </button>
      ) : (
        <Link {...props}>
          <a className={className}>{props.children}</a>
        </Link>
      )}
    </>
  );
};

export default Button;

こうしておけば href も onClick も同じような感覚で渡す事ができそう。

<Button as={`/xxx/${xxx}`} href="/xxx/[xxx]" prefetch>
  xxx
</Button>
<Button onClick={onClick}>xxx</Button>

ここまで書いたところで思ったんですが、やはりこういったラッパー的なものを作るのは個人制作の時以外はあんまりやんない方が良さそうな気もしますね…見た人が混乱しそう。

しかしあちこちに重複する表記があるのも混乱の元だし一体どうするのが正解なんだろう…

comments powered by Disqus
Profile
😛

石原 悠 / Yu Ishihara

デザインとプログラミングとヨーグルト作りが好きです。