'use client' のコンポーネント本体に window を直接書いても、サーバーでは実行されないので安全ですか。
安全ではありません。サーバーでも一度実行されるため、本体に window を書くとそこで落ちます。公式も「Client Component は既定でサーバー上でプリレンダーされる」と書いています。
面接官が見ているのは最頻出の誤解。ここを外すと初期表示の設計を誤る。
よくある答えと、面談でどう見られるか
- 安全ではない。サーバーでもプリレンダーされるので、そこで落ちる
その通りです。公式も「Client Component は既定でサーバー上でプリレンダーされる」と書いています。 - 安全。'use client' を付けた時点でクライアント専用になる
ここが最頻出の誤解です。サーバーでも実行されます。この理解のままだとコンポーネント本体に window を書いてしまい、サーバー側の実行で落ちます。 - 安全ではない。本体は評価されるので、useEffect の中に移す必要がある
正確です。本体はサーバーでも評価されますが、useEffect はマウント後なのでサーバーでは走りません。だからブラウザ専用のAPIは useEffect の中に置きます。 - 開発環境では落ちるが、本番ビルドではクライアントのみになるので問題ない
環境で変わるものではありません。本番でもプリレンダーされます。「本番だけ違う」と考えると、本番で出る不具合の原因を見誤ります。
面接官は何を見ているか
- サーバーでも実行される(プリレンダーされる)と答えた
- 「クライアント専用」ではなく「クライアントでも動く」だと言えた
- だから window に触ると落ちる、と繋げられた
模範解答
安全ではありません。サーバーでも実行されます。これは非常によくある誤解です。
公式は「Client Component は既定でサーバー上でプリレンダーされる。クライアント側の JavaScript を実行する能力が追加されたもの、と考えるとよい」と書いています。'use client' は「クライアント専用」ではなく「クライアントでも動く」です。
初回ロードの流れはこうです。まずサーバーで HTML を作って即座に表示し、RSC ペイロードでツリーを突き合わせ、最後に JavaScript でハイドレーションして操作可能にします。
実務で効いてくるのは、この「サーバーでも1回実行される」という事実です。コンポーネント本体に window や localStorage を直接書くと、サーバー側の実行で落ちます。useEffect の中に入れるか、ブラウザで動いているかを確認してから触る必要があります。
ここからどう深掘りされるか
この問いに答えられた場合、面談は次の質問に進みます。
観点をすべて押さえられた場合
「Hydration failed」というエラーが出ました。何が起きていますか。一部しか触れられなかった場合
サーバーでレンダリングする意味は何ですか。全部クライアントで描画するのと比べて。触れられなかった場合
サーバーでレンダリングする意味は何ですか。全部クライアントで描画するのと比べて。