Next.jsの"use client";とは

これまでのあらすじ
Next UIでモーダルを追加しようとしたら、ファイルの先頭に"use client";
という謎の文字列を追加しろというエラーが出て、言われた通りにすると確かにエラーは消えたけど、何がどう変わったの?助けて、ChatGPT〜〜
なんとなくJavaScript書いてると思ってたけど
まず前提として、Next.jsで書いてるReactコンポーネントは、TypeScript(正しくはJSX)で記述しているけど、全部が全部、従来<script>
タグで括られてきたようなJavaScriptのコードというわけではない。ただのDOMもある。たとえばこんなのはただのDOM。
export default function App() {
return <div>Hello World!</div>
}
たしかに??言われてみると、ただのDOMだね??(今気づいたんかい)
ただのDOMはサーバーサイドでレンダリングしちゃう
ただのDOMはサーバーサイドでレンダリングしたものをクライアントに送るのがNext.jsスタイル。たとえば上記のファイルはサーバーサイドで<div>Hello World!</div>
というDOMに変換された状態でブラウザに送られます。ブラウザ側はDOMを読み取るだけなので軽量、SEO的にもGood。
"use client";
の正体とは
"use client";
はただのDOMじゃなくてクライアントのブラウザ側でJSの処理が必要なファイルにつけるフラグで、「これはただのDOMじゃないよ〜JSファイルとしてクライアントサイドに送ってね〜」と伝えているらしい。だからモーダルで必要だったんだぁ! モーダルは、Onclick
とかクライアントサイド側の処理てんこ盛りですからね。
どんなときに"use client";
が必要?
ここら辺はまだよくわかってないけど、以下の場合はファイルに"use client";
をつけないとエラーになるみたい。
useState
、useEffect
、useReducer
、useContext
などのReactフックを使うときonClick
、onChange
、onSubmit
などのイベントを使うときlocalStorage
、sessionStorage
のようなブラウザのAPIにアクセスするとき- インポートしてるライブラリで必要なとき
もしただのDOMに"use client";
をつけたら
こういうことが起きる。
- Next.jsがクライアントサイドのJSだと解釈して、クライアントサイドに空の
<div>
と実行可能なJSを送る - クライアントサイドにおいてJSにより空の
<div>
が<div>Hello World!</div>
に変換される
パフォーマンス的にもSEO的にもNo Goodだよー。
だから、デフォルトはサーバーサイド、必要なときだけ"use client";
を使うっていうのが基本みたい。
SSGとの関係
このブログで使ってるStatic Site Generation(SSG)はビルド時にサーバーサイドで静的HTMLを生成するという仕組みだけど、"use client";
とも共存できる。SSGでは基本全て静的HTMLになるけど、"use client;"
なコンポーネントだけはクライアントサイド側のJSとして扱われる。こりゃ便利だねー
というわけで、モヤモヤがちょっと晴れる"use client";
の話でした。