本文へ移動

ホーム / Web / 第3部 フロントエンド

第3部 フロントエンド・第6章

フロントエンドのフレームワークと描画方式

★★★ 必須9トピック・面接 5問

React/Next.js を例に、画面をどう組み立て、どこで描画するかを押さえる。

6.1React の仕組み

用語★★★ 必須
ひとことで

状態が変わるとコンポーネントを描き直し、差分だけを実際の画面に反映する。

React は、画面をコンポーネント(部品の関数)で組み立てるライブラリです。コンポーネントは「データを受け取って、画面の形を返す関数」で、データが変わると React が関数を呼び直し、前回との差分だけを実際の DOM に反映します。

状態が変わってから画面に出るまで状態が変わるsetX()・props の変化関数を呼び直す子のコンポーネントも前回と比べる差分を計算DOM に反映変わった所だけmemo で子を飛ばせるuseEffect を実行描画のあとeffect の中で setX すると、もう一周する(使いすぎに注意)
React の再描画の流れ

状態・props・副作用

しくみ役割
props親から渡される値。子は書き換えない
状態(useState)そのコンポーネントが持つ値。setX で変えると再描画される
副作用(useEffect)描画のあとに、外の世界と同期する処理(購読・タイマー・DOM の直接操作)
function Clock() {
  const [now, setNow] = useState(Date.now());
  useEffect(() => {
    const id = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(id); // 片付け
  }, []);
  return <p>{new Date(now).toLocaleTimeString()}</p>;
}

面接ではこう答える

React は、画面をコンポーネントという関数で組み立てるライブラリです。コンポーネントは props と状態を受け取って画面の形を返し、状態が変わると React が関数を呼び直して、前回との差分だけを実際の DOM に反映します。props は親から受け取って書き換えない値、状態は useState で持つ値で、setter で変えると再描画されます。

6.2useEffect の使いどころ

用語★★★ 必須
ひとことで

useEffect は描画のあとに React の外の世界(購読・タイマー・DOM)と同期するための仕組み。計算やイベントへの反応には使わない。

effect は「React の外」と同期するときだけeffect が要らない・props から計算できる値・クリックへの反応・(イベントの処理に書く)・データ取得はライブラリにeffect を使う・外の購読・タイマー・DOM を直接触る・外部のウィジェットとの同期・片付けを return で書く
useEffect が要る場面と要らない場面

よくある失敗は useEffect の使いすぎです。props から計算できる値は描画中に計算すればよく、状態にコピーして effect で同期すると、ずれや余計な再描画の原因になります。データの取得も、自前の effect より TanStack Query などのライブラリやフレームワークの仕組みを使うほうが、競合やキャッシュを扱えます。依存配列の書き漏れは lint(react-hooks/exhaustive-deps)で防ぎます。

// よくない:計算できる値を状態にコピーして effect で同期
const [full, setFull] = useState("");
useEffect(() => setFull(first + " " + last), [first, last]);
// よい:描画中に計算する
const full = first + " " + last;

開発中の Strict Mode では、片付けの漏れに気づけるよう effect が2回実行されます。2回動いて困る effect は、片付け(return)が足りていない合図です。

面接ではこう答える

useEffect は、描画が終わったあとに、React の外にあるもの、たとえばタイマーや WebSocket の購読、DOM の直接操作と同期するための仕組みです。props から計算できる値を状態にコピーして effect で同期するのはよくある失敗で、ずれや余計な再描画の原因になります。クリックへの反応はイベントの処理に書き、データの取得は TanStack Query やフレームワークの仕組みに任せます。片付けの処理を return で書くのも大事です。

直す前に、まず測るProfiler で測る遅い部品を特定状態を近くに影響の範囲を狭くメモ化memo・useMemo一覧の仮想化見える行だけ
再描画の問題を直す順番

親が再描画されると子も全部呼び直されます。たいていは十分速いので、まず React DevTools の Profiler で本当に遅い所を測ってから直します。

  • 状態を使う場所の近くに置き、影響する範囲を狭くする。
  • memo(props が同じなら子を飛ばす)、useMemo(重い計算の結果を使い回す)、useCallback(関数を同じものにして memo を効かせる)。
  • 長い一覧は仮想化(見えている行だけ描く)。
  • React Compiler を使うと、メモ化を自動で入れてくれる。

6.4Server Components

用語★★★ 必須
ひとことで

サーバーだけで実行され、JS をブラウザに送らないコンポーネント。データ取得はサーバーで、操作のある部分だけを Client Component にする。

サーバーで描ける所はサーバーで。動く所だけ JS を送るサーバーServer Componentページ・一覧DB・API秘密情報も使えるClient Component"use client"ブラウザHTML(描画の結果)JS は送らないClient の JS だけ状態・クリック
Server Component と Client Component の境目

React Server Components(RSC)は、サーバーだけで実行されるコンポーネントです。DB や API から直接データを取って HTML の元になるものを作り、そのコンポーネントの JS はブラウザに送りません。送る JS が減り、データ取得の往復も減ります。クリックや状態を使う部分だけを "use client" を付けた Client Component にします。Next.js の App Router では既定が Server Component です。サーバーの秘密情報を Client Component に props で渡すとブラウザに届くので注意します。

Server ComponentClient Component
動く場所サーバーだけ(ビルド時かリクエスト時)サーバーで HTML を作り、ブラウザでも動く
できることDB・秘密情報に直接アクセス、重いライブラリを使う状態・effect・クリックなどのイベント
ブラウザに送る JSなしあり
書き方既定(App Router)先頭に "use client"

面接ではこう答える

React Server Components は、サーバーだけで実行されるコンポーネントです。DB や API から直接データを取って描画でき、そのコンポーネントの JavaScript はブラウザに送りません。そのため送る JS が減り、データ取得の往復も減ります。クリックや状態を使う部分だけを "use client" の Client Component にして、境目で渡す props はシリアライズできる値に限ります。秘密情報を Client Component に渡すとブラウザに届くので注意します。

6.5状態管理

用語★★☆ 重要
ひとことで

画面の状態・サーバーのデータ・URL を分けて管理する。サーバーのデータはキャッシュとして扱う(TanStack Query など)。

状態管理で一番大事なのは、どのライブラリを使うかより状態をどこに置くかです。状態は種類によって置き場所が決まります。

上から順に当てはまるか考えるサーバーから取ったデータ?TanStack Query・SWR のキャッシュはいURL に残したい?(検索条件など)URL のクエリはい1つの部品の中だけで使う?その部品の useStateはい近くの部品で共有する?共通の親に上げて props で渡すはいどれでもない(本当に全体で使う)Context・Zustand など(最後に)下に行くほど、どこから変わったか追いにくくなる
状態をどこに置くかの決め方
種類例置き場所
部品の中だけの状態開閉・入力中の文字そのコンポーネントの useState
サーバーのデータユーザー・商品一覧TanStack Query・SWR などのキャッシュ(取得・再取得・期限を任せる)
URL に残したい状態検索条件・ページ番号・タブURL のクエリ(共有・戻るボタンが効く)
フォーム入力値・エラーReact Hook Form などのフォームライブラリ
本当に全体で使う状態ログイン中のユーザー・テーマContext、Zustand・Redux など

グローバル状態を増やしすぎない

何でもグローバルなストアに入れると、どこから変わったか追いにくくなり、関係ない部品まで再描画されます。特に、サーバーのデータをストアにコピーすると「古いままになる」「更新後に再取得し忘れる」問題が起きやすいので、サーバーのデータはサーバー用のキャッシュに任せます。まず近くに置き、2つの部品で共有が必要になったら共通の親に上げる、それでも遠いときにだけグローバルにする、の順で考えます。

面接ではこう答える

状態管理で一番大事なのは、どのライブラリを使うかより、状態をどこに置くかです。部品の中だけの状態はその部品の useState、サーバーのデータは TanStack Query などのキャッシュ、検索条件のように共有したいものは URL、本当に全体で使うものだけをグローバルなストアに置きます。まず近くに置き、共有が必要になったら共通の親に上げる、という順で考えます。

ひとことで

API のデータはサーバーにある本物の写し。TanStack Query などに、取得・キャッシュ・再取得・無効化を任せる。

画面はキャッシュを読み、古ければ裏で取り直す画面の部品useQuery(["user", 42])クエリのキャッシュキーごとに保存・期限APIサーバーの本物古ければ取り直す更新したら invalidateQueries でキーを無効化 → 自動で再取得
サーバーのデータを、キャッシュの層を通して読む

API から取ったデータは「サーバーにある本物の写し」です。自分で状態に入れて管理するより、TanStack Query・SWR などのサーバー状態のライブラリに、取得・キャッシュ・再取得・期限を任せます。

ライブラリがしてくれること自分で書くと起きがちなこと
同じキーの取得を1回にまとめる同じ API を部品ごとに何度も呼ぶ
古くなったら裏で取り直す(stale-while-revalidate)画面を開き直すまで古いまま
更新したら関係するキーを無効化(invalidateQueries)更新後の再取得を忘れる
遅い応答が後から来ても上書きしない検索語を変えたのに前の結果が表示される
読み込み中・エラー・再試行の状態フラグが増えて矛盾する

楽観的更新(サーバーの応答を待たずに画面を先に変え、失敗したら戻す)も、これらのライブラリの仕組みを使うと安全に書けます。

面接ではこう答える

API から取ったデータは、画面の状態ではなくサーバーにある本物の写しなので、キャッシュとして扱います。TanStack Query や SWR を使うと、同じキーの取得をまとめ、古くなったら裏で取り直し、更新したら関係するキーを無効化してくれます。自前で状態に入れると、再取得し忘れて古いままになったり、遅れて届いた応答で上書きされたりする問題が起きやすくなります。

6.7CSR・SSR・SSG・ISR

用語★★★ 必須
ひとことで

どこで HTML を作るかの違い。初回表示の速さ・SEO・サーバー負荷・鮮度のトレードオフ。

HTML をいつ・どこで作るかで、描画の方式が分かれます。

HTML の中身を「いつ・どこで」作るかビルドのときリクエストのときブラウザSSGHTML を作るハイドレーションISRHTML を作る期限ごとに作り直すハイドレーションSSR毎回 HTML を作るハイドレーションCSR空の HTML と JSJS で画面を作る濃い箱:ページの中身ができる場所。SSR・SSG もボタンを動かすにはブラウザでハイドレーションが要る
HTML の中身をいつ・どこで作るか
方式HTML を作るとき向いているもの弱点
CSR(クライアント描画)ブラウザで JS が実行されてからログイン後の管理画面・操作の多いアプリ初回表示が遅い、SEO に不利、JS が大きい
SSR(サーバー描画)リクエストのたびにサーバーでユーザーごと・最新が必要で SEO も必要なページサーバーの費用と負荷、TTFB が処理時間に左右される
SSG(静的生成)ビルドのときに1回ドキュメント・ブログ・LP更新にはビルドし直し、ページ数が多いとビルドが長い
ISR(段階的な再生成)最初はビルドや初回アクセス時、その後は期限ごと・指示で作り直す商品ページ・記事など、少し古くてよい大量のページ一時的に古い内容が出る、仕組みが基盤に依存する

1つのサイトでもページごとに選べます。例:トップと記事は SSG/ISR、検索結果は SSR、マイページは CSR。判断の軸は初回表示の速さ・SEO・データの鮮度・サーバーの費用です。

面接ではこう答える

描画方式は、HTML をいつ、どこで作るかの違いです。CSR はブラウザで JS が動いてから作り、SSR はリクエストのたびにサーバーで、SSG はビルドのときに1回、ISR は静的に作ったものを期限ごとに作り直します。初回表示の速さ、SEO、データの鮮度、サーバーの費用のトレードオフで、ページごとに選び分けます。

6.8ハイドレーション

用語★★★ 必須
ひとことで

サーバーで作った HTML に、ブラウザで JS がイベントを結びつけて「動く画面」にする処理。

「見える」と「押せる」の間に、JS の読み込みと実行があるHTML が届く表示(LCP)JS が届くハイドレーション完了見えるが押せない時間(JS が大きいほど長い)縮める:送る JS を減らす・Server Components・動く所だけハイドレーション
表示されてから操作できるまでには間がある

SSR や SSG で届いた HTML は、見えてもまだボタンが動きません。ブラウザで JS を読み込み、React がその HTML にイベントを結びつけて「動く画面」にする処理をハイドレーションと呼びます。

  • JS が大きいと、表示されてから押せるまでの間が長くなる。Server Components や部分的なハイドレーション(アイランド)で、動かす所だけに絞る。
  • サーバーとブラウザで描画結果が違うと「hydration mismatch」の警告が出る。Date.now()・乱数・window の参照・タイムゾーンが原因になりやすい。
hydration mismatch の原因直し方
Date.now()・乱数サーバーで決めた値を props で渡す。表示は effect のあとに
window・localStorage を描画中に読むuseEffect の中で読む、Client だけで描く部品にする
タイムゾーン・ロケールの違い表示する形式とタイムゾーンをそろえる
不正な HTML の入れ子(p の中に div)ブラウザが直してしまうので、正しい入れ子にする

面接ではこう答える

SSR や SSG で届いた HTML は表示されても、まだボタンは動きません。ブラウザで JavaScript を読み込み、React がその HTML に対応する部品を作ってイベントを結びつける処理をハイドレーションと呼びます。JS が大きいと表示から操作できるまでの間が長くなるので、Server Components などで動かす所だけに絞ります。サーバーとブラウザで描画結果が違うと mismatch の警告が出るので、時刻や window の参照に注意します。

6.9エッジでの描画

★★☆ 重要
ユーザーには近いが、DB からは遠いことがあるユーザー東京エッジ東京の拠点DB米国のリージョン近い遠い往復 × クエリの回数エッジ向き:リダイレクト・A/B の振り分け・認証の確認・キャッシュの判定DB の近く向き:DB を何度も読むページの描画・更新の処理
エッジと DB の距離

CDN の拠点(エッジ)でサーバー描画を動かすと、ユーザーに近い所で HTML を返せて TTFB が短くなります。ただしエッジで使える機能は限られ(Node.js の一部の API が使えないなど)、DB が1か所にあると、エッジから DB への往復で逆に遅くなることがあります。DB を使うページは DB の近くで、DB を使わない処理(リダイレクト・A/B の振り分け・認証の確認)はエッジで、と分けるのが基本です。

この章のまとめ

🖨 まとめシート(印刷・PDF)
  • React の仕組み(状態・再描画)と状態管理の選び方
  • CSR・SSR・SSG・ISR の違いと使い分け
  • React の仕組み:状態が変わるとコンポーネントを描き直し、差分だけを実際の画面に反映する。
  • useEffect の使いどころ:useEffect は描画のあとに React の外の世界(購読・タイマー・DOM)と同期するための仕組み。計算やイベントへの反応には使わない。
  • Server Components:サーバーだけで実行され、JS をブラウザに送らないコンポーネント。データ取得はサーバーで、操作のある部分だけを Client Component にする。
  • 状態管理:画面の状態・サーバーのデータ・URL を分けて管理する。サーバーのデータはキャッシュとして扱う(TanStack Query など)。
  • サーバーのデータはキャッシュとして扱う:API のデータはサーバーにある本物の写し。TanStack Query などに、取得・キャッシュ・再取得・無効化を任せる。
  • CSR・SSR・SSG・ISR:どこで HTML を作るかの違い。初回表示の速さ・SEO・サーバー負荷・鮮度のトレードオフ。
  • ハイドレーション:サーバーで作った HTML に、ブラウザで JS がイベントを結びつけて「動く画面」にする処理。

この章のクイズ

面接ではこう聞かれる

まず答えを見ずに声に出して答え、そのあと開いて比べる。

Q1CSR と SSR の違いと使い分けは?

模範回答

CSR はブラウザで JS を動かして画面を作る方式で、サーバーは静的なファイルを返すだけなので安く、画面遷移後の操作は速いですが、初回表示が遅く、SEO にも不利です。SSR はリクエストごとにサーバーで HTML を作るので、初回表示が速く SEO にも強く、ユーザーごとの最新のデータも出せますが、サーバーの費用と負荷がかかり、処理が遅いと TTFB も遅くなります。

使い分けは、検索から来る公開ページで鮮度も必要なら SSR、あまり変わらないなら SSG や ISR、ログイン後の管理画面のように SEO が要らず操作が多いなら CSR です。今のフレームワークはページごとに選べるので、ページの性質で決めています。SSR でもハイドレーションの JS が重いと押せるまでが遅いので、Server Components で JS を減らすことも合わせて考えます。

深掘りされたら

  • ハイドレーションのエラーはなぜ起きますか?
  • ISR で古い内容が出るのが困る場合は?

見られているポイントトレードオフ(初回表示・SEO・コスト・鮮度)

Q2useEffect はどんなときに使いますか? 使いすぎるとどうなりますか?

模範回答

useEffect は、描画のあとに外の世界と同期するために使います。例えば、イベントの購読・タイマー・WebSocket の接続・DOM を直接操作するライブラリとの連携です。片付けの関数を返して、外れたときに購読を止めます。

使いすぎの典型は、props から計算できる値を state にコピーして effect で同期することです。描画が2回走り、値がずれる原因になります。計算できる値は描画中に計算し、ユーザーの操作に反応する処理はイベントハンドラーに書きます。データの取得も、競合やキャッシュを扱えるライブラリやフレームワークの仕組みに任せるほうが安全です。

深掘りされたら

  • 依存配列を空にするとどうなりますか?

見られているポイント外部との同期という役割と、典型的な誤用

Q3React の画面が遅いとき、どう調べて直しますか?

模範回答

まず React DevTools の Profiler で操作を記録し、どのコンポーネントが何回、何 ms かけて描画されているかを見ます。推測でメモ化を足すより、遅い所を特定するのが先です。

よくある原因は、状態を上の方に置いていて関係ない子まで再描画される、長い一覧を全部描いている、毎回新しいオブジェクトや関数を props に渡して memo が効かない、の3つです。直し方は、状態を使う場所の近くに移す、一覧を仮想化する、memo・useMemo・useCallback を必要な所にだけ入れる、です。直したら同じ操作で測り直します。

深掘りされたら

  • memo を全部のコンポーネントに付けないのはなぜですか?

見られているポイント計測してから直す、原因の典型

Q4Server Components とは何ですか? 何がうれしいのですか?

模範回答

サーバーだけで実行される React のコンポーネントです。DB や API から直接データを取って画面の元を作り、そのコンポーネントの JavaScript はブラウザに送りません。

うれしいのは、送る JS が減って表示と操作の開始が速くなること、データ取得がサーバーの中で済むので往復が減ること、秘密の情報をサーバーに閉じたまま使えることです。クリックや状態が要る部分だけを "use client" の Client Component にします。注意点は、Server Component から Client Component に渡した props はブラウザに届くので、秘密を渡さないこと、そしてどこがサーバーでどこがブラウザかの境目を意識して設計することです。

深掘りされたら

  • SSR とは何が違いますか?

見られているポイントJS を送らない仕組みと境目の注意

Q5ハイドレーションとは何ですか? よくある問題は?

模範回答

サーバーで作った HTML はブラウザに表示されても、そのままではボタンが動きません。ブラウザで JS を読み込み、React がその HTML にイベントを結びつけて動く画面にする処理がハイドレーションです。

よくある問題は2つあります。1つは、JS が大きいと表示されてから押せるまでの間が長くなることで、Server Components やコード分割で JS を減らします。もう1つは、サーバーとブラウザで描画結果が違うと mismatch の警告が出ることで、現在時刻・乱数・window の参照・タイムゾーンの違いが原因になりやすいです。ブラウザでしか決まらない値は、描画後に effect で入れます。

深掘りされたら

  • アイランドアーキテクチャとは何ですか?

見られているポイント仕組みと、遅さ・mismatch の原因