サーバー上でもレンダリングされるのにClient Componentsって名前はわかりにくいなぁ

# はじめに

皆さんは`Next.js`を使ってWeb開発をしていますか？私は`Next.js`が好きでよく利用していますが、少しだけ不満に思う点があります。それは`Client Components`に関することです。

`Next.js`の`App Router`では作成したコンポーネントはデフォルトで**サーバーのみでレンダリングをされる**`Server Components`となります。また、`Server Components`登場以前からあるいわゆる「標準的な」Reactコンポーネント（`Client Components`と呼ばれる）に切り替えて使うこともできます。

しかし、`Client Components`という名前だとまるで**クライアントのみでしかレンダリングされない**見たいじゃないですか。`Server Components`が**サーバーでのみレンダリングされる**ことから余計にそう思ってしまいます。

実際、私自身も`Next.js`の`App Router`を学び始めの頃はずっとそう思っていました。元々`Pages Router`から`Next.js`を使い始め、`App Router`に移行した際、しばらくの間、ドキュメントを読まずに「雰囲気」で使っていた（今もかもしれません…）のですが、ある日ドキュメントを読んで初めて気づきました。

個人的には`Pages Router`からしっかり学んでいた方は`Client Components`の誤解はないかもしれないですが、`App Router`からやり始めた方や過去の自分みたいに全くドキュメントを見ない人は誤解してしまっているかもしれません。

ってことでドキュメント見ながら、`Next.js`のレンダリングについてご紹介します。

:::note warn
私自身、まだWeb開発初心者なので、内容に誤りがあるかもしれません。その場合はぜひご指摘いただけると嬉しいです。
:::

## Client Components

`Next.js`のレンダリング > クラアントコンポーネントを見ると、すぐにサーバー上でレンダリングされるということが書いてありました。

https://nextjs.org/docs/app/building-your-application/rendering/client-components

![スクリーンショット 2024-12-05 8.23.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3750522/601cdef1-7ecb-237a-507f-11e0e642a17c.png)

でも、事前レンダリングってなんだってなりますし、サーバー側でレンダリングして、どうやってインタラクティブなUIを実現するのでしょうか。もう少し読み進めてみます。

下のスクショではどのように`Client Components`がレンダリングされているかが書かれています。簡単に説明すると、サーバーで静的HTMLをレンダリングし、それがブラウザに表示された後、JSファイルをダウンロードしてインタラクティブなUIを実現している、という流れです。

![スクリーンショット 2024-12-05 8.41.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3750522/0ef1067c-226d-757a-50a5-69c1e9e8cf6e.png)

スクショの最後にある「**水分補給**」とは、サーバーでレンダリングされたHTMLにクライアント側でインタラクティブ性を加えるプロセスのことを指します。この点については、akiさんの記事が視覚的に非常にわかりやすいです。

https://zenn.dev/ak/articles/dd60f8b1712628

これによって、クライアント側でJSのロード、実行に時間がかかり、Reactコンポーネントがレンダリングされず、しばらく画面が白くなってしまう問題や、レンダリング前の要素のないHTMLがクローラーに渡されることでSEOの低迷してしまう問題を解消しています。

# Server Components

`Server Components`について詳しく説明すると本題から逸れてしまうので、ここでは簡単に触れるだけにします。当然ながら、`Server Components`はサーバー側でレンダリングされます。

https://nextjs.org/docs/app/building-your-application/rendering/server-components

![スクリーンショット 2024-12-05 11.27.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3750522/d68cd00b-a62b-d3df-203c-00071d05f0b0.png)

また、JSをロード・実行し、インタラクティブにするプロセスであるハイドレーションは行われていません。詳しいレンダリングの詳細に「水分補給」という言葉がありますが、これはクライアントコンポーネントの話をしています。

![スクリーンショット 2024-12-05 11.43.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3750522/97655e22-4537-1aa0-bb08-fe13470b8ca4.png)


# 結論

`Client Components`は、サーバー側で初期HTMLを生成し、クライアント側でハイドレーションを通じてインタラクティブ性を持つため、サーバーとクライアントの両方でレンダリングされます。一方、`Server Components`はサーバー側でのみレンダリングされ、生成された静的HTMLがクライアントに送信されます。

|   | Server Rendering | Client Rendering |
|--------------------|--------------------|---------------------------------|
| Client Components | ⭕️  | ⭕️  |
| Server Components | ⭕️ | ❌ |


:::note warn
警告
たとえ`Client Components`でフックを使用せず、インタラクティブ性がゼロであっても、そのコンポーネントはクライアント側でのハイドレーションが行われます。
:::

# 余談
じゃあ、なんて名前にするのがいいかという話なんですが、`Standard Components`というのはどうでしょうか。これは「標準的な」Reactコンポーネントを表すのに適切な気がしています。これに伴って、ディレクティブも`"use standard"`とかにしては良いのではないでしょうか。

```react:新しい案
"use standard";

import { useState } from "react";

export const Home = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h1>Counter Example</h1>
      <p>Current Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};
 ```

:::note warn
これはマジで余談なんで呼び飛ばしてもらって構いません。もしなにか良さげな名前あったらコメント欄とかで教えてほしいです！
:::