どちらに置くか

迷ったときの判断基準

部品ごとに "use client" を書くかどうかは、感覚で決めるものではありません。次の4つのどれか1つでも当てはまればクライアント、どれも当てはまらなければサーバーです。

  1. state を持つuseStateuseReducer で値を持ち続ける
  2. イベントを受け取るonClickonChangeonSubmit が付いている
  3. ブラウザだけにあるものを使うwindow document localStorage など
  4. フックを使うuseEffect や自作フック、useRouter のようなものも含む

上から順に見ていって、1つでも当たったらそこで打ち切ってクライアントにします。全部外れたらサーバーのままにします。

fleama で当てはめてみる

部品当てはまるもの置き場所
ItemCardどれも無いサーバー
ItemListどれも無いサーバー
SearchBoxstate とイベントクライアント
CartButtonイベントクライアント
ThemeTogglelocalStorageクライアント

表示するだけの部品はほとんどサーバーに残ります。ブラウザ側に移るのは、受講生が指で触る部分だけだと考えると、だいたい合っています。

迷いやすいところ

map で一覧を並べるのは state ではないので、サーバーのままで構いません。日付を整形する関数も、計算しているだけならサーバーで動きます。逆に、一見ただの表示に見えても new Date() の結果をそのまま出すものは、サーバーとブラウザで表示がずれることがあるので注意が要ります。

判断に迷ったら、まずサーバーのままにしてみて、動かなくなってからクライアントにするのが安全です。あとから足すのは簡単ですが、いちど広げた境界を戻すのは手間がかかります。

演習

判断基準を関数にして、部品を自動で仕分けます。

ヒント

layout.tsx
page.tsx
プレビュー

できているか

  • 6つの部品を仕分けている
  • サーバーに残す部品が3つある
  • クライアントに移す部品が3つある
  • 表示だけの ItemCard はサーバー
  • state を持つ SearchBox はクライアント
  • イベントを受け取る CartButton はクライアント
  • ブラウザ API を使う ThemeToggle はクライアント
  • 仕分けの結果が表に出ている
  • state の有無を判断に使っている
  • ブラウザ API の有無を判断に使っている