🥗

[Next.js]サーバーコンポーネント内でボタンを押す

に公開

サーバーコンポーネント内で、ボタンを押した時にwindow.confirm()を呼びたいケースがありました。

しかし、サーバーコンポーネントはクライアントサイドのイベントハンドラ(onClick)をサポートしていないためエラーになってしまいます。

↓これはダメ

export default async function Page() {
  const handleClick = () => {
    window.confirm(
      "サーバーコンポーネントでは使えない"
    );

  }
  return (
    <div>
      ...

      <button onClick={handleClick} />
    </div>
  );
}

解決方法

これを解決するためには、コンポーネントをクライアントコンポーネントにする必要があります。

ただ、コンポーネント全体をクライアントコンポーネントにはしたくなかったので、buttonの箇所だけをクライアントコンポーネントとして切り出す必要がありました。

export default async function Page() {
  return (
    <div>
      ...

      <Button />
    </div>
  );
}
"use client";

export const Button: FC = () => {
  const handleClick = () => {
    window.confirm(
      "クライアントコンポーネントなので使える"
    );
  };
  return (
    <button onClick={handleClick} />
  );
};

まとめ

クライアントコンポーネントを切り分けることで、サーバーコンポーネント内でも動的な処理が扱えるとわかりました。

正直reactをずっとやっていた身からすると、こういう切り分けはしたくありませんでした。

また、切り分けたコンポーネント内(ボタン)で処理を呼ぶのもあまり好きじゃないです。(上位のコンポーネントにまとめたい...)

どういうふうに綺麗に書けるのか、ベストプラクティスはなんなのか、もっと知る必要があると思いました。

Discussion