💡
buttonとaタグの両方に対応するonClickイベント
はじめに
Reactでボタンやリンクのクリックイベントを処理する際、buttonタグとaタグではイベントの型が異なるため、同じonClickハンドラを使用することが難しくなります。この問題を解決し、両方のタグに対応する汎用的なonClickハンドラを実装する方法について解説します。
問題
通常、buttonタグとaタグの両方に対応するコンポーネントを作成する際、onClickイベントの型の違いにより、型エラーが発生します。HTMLButtonElementとHTMLAnchorElementのイベント型が異なるため、同じonClickハンドラを共有することが困難です。
const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
};
このコードは、HTMLButtonElementに特化した型を使用しているため、HTMLAnchorElementに対しては互換性がありません。
解決方法
イベントのターゲットをHTMLElementとして扱い、buttonとaタグの両方に対応するようにします。
実装例
以下のコードは、buttonとaの両方に対応するButtonコンポーネントの実装例です。
import { PropsWithChildren } from "react";
import Link from "next/link";
type Props = PropsWithChildren<{
href?: string;
onClick: (e: React.MouseEvent<HTMLElement>) => void;
}>;
export const Button = ({ href, onClick, children }: Props) => {
if (href) {
return (
<Link href={href} onClick={onClick}>
{children}
</Link>
);
}
return <button onClick={onClick}>{children}</button>;
};
おわりに
この方法を用いることで、buttonとaの両方に対応する汎用的なonClickイベントハンドラを実装することができます。
Discussion