009. 状態管理のサーバー集中(Centralized Server State Management)
原理:「真実の場所」を一箇所に決める
状態管理――Web開発最大の「苦しみ」
Webアプリケーションを開発する際、最も頭を悩ませるのは「状態(State)」の扱いです。 状態とは、例えば「ユーザーはログインしているか?」「ショッピングカートの中身は何点か?」「検索欄には何と打たれているか?」といった、刻一刻と変化する情報の断片です。
モダンなフロントエンド開発(Reactなど)では、この「状態」をブラウザ側のメモリに保持し、管理します。しかし、これは「真実のコピーを二つ作る」という危険な行為です。 1. サーバー側の真実: データベースに保存されている「本当の」データ。 2. クライアント側の真実: ブラウザのJSメモリに一時的に保存されているデータ。
この二つを常に、完璧に一致させ続けるのは至難の業です。 「サーバー側では削除に失敗したのに、ブラウザの画面上では消えたままになっている」といった「状態の不一致」が生じると、ユーザーは深刻な混乱に陥ります。これを解決するために、Reduxといった複雑なツールが登場しましたが、それは毒を毒で制するような、さらなる複雑さの始まりでもありました。
HTMXの解答:真実はサーバーにのみ宿る
HTMXの「状態管理のサーバー集中」という原理は、この問題を根底から覆します。 その答えは極めてシンプル。「ブラウザ側で状態を一切持たない」という決断です。
HTMXを使ったアプリにおいて、ブラウザは「現在の状態」を記憶しません。 「今、カートに何が入っているか?」をブラウザに聞いても、ブラウザは「知りません。サーバーからそう表示しろというHTMLが届いたので、それを映しているだけです」と答えます。
すべての状態判断は、サーバー(真実の館)で行われます。HTMLを生成するその瞬間、サーバーが最新のデータベースを参照し、正しい画面を作り上げる。ブラウザはそれを表示する。 これにより、クライアントとサーバーの「データのズレ」という概念そのものがこの世から消滅します。
実践:JSの変数を捨ててサーバーに任せる
1. タスクの完了状態の切り替え
例えば、ToDoリストでタスクを「完了」にする処理を見てみましょう。
【ブラウザで管理する場合(従来のJS)】
JSの配列の中から対象のIDを探し、completed フラグを true に書き換え、画面を再描画……。その裏でサーバーにもAPIを叩いて、もし通信に失敗したら画面を元に戻す処理を書く必要があります。
【HTMXで管理する場合】 ただボタンを押し、サーバーに「これを完了にして」と投げるだけです。
<!-- index.html -->
<div id="task-item-42">
<p>タスク:部屋の掃除</p>
<!-- 通信の結果、この <div> まるごとがサーバーから届く新しいHTMLに置き換わる -->
<button hx-post="/tasks/complete/42" hx-target="#task-item-42">
完了する
</button>
</div>
2. コンテンツのトグル(表示・非表示)
「もっと見る」ボタンで追加情報を出すような処理も、サーバーに状態を預けます。
<div id="details">
<button hx-get="/api/details/show" hx-target="#details">
詳細を表示
</button>
</div>
<!-- サーバーが「詳細が含まれたHTML」を返し、そこには「閉じる」ボタンも含まれている -->
3. ステップ・バイ・ステップ解説
- リサーチの放棄: ブラウザ側で「いま、詳細が開いているか?」という変数(
isOpenなど)を作るのをやめます。 - アクションの委譲: ユーザーが操作したら、とにかくサーバーに「今のリクエスト」を送ります。
- サーバーの全責任: サーバーは「よし、今は詳細を開くモードだな」と判断し、それに対応したHTMLパーツを返します。
- 結果の受容: ブラウザは届いたHTMLをパコンとはめるだけ。
「今どうなっているか」をブラウザが知る必要はありません。次にやるべきことが書かれたHTMLが、常にサーバーから届くからです。
比較:分散管理(苦行) vs 集中管理(至福)
分散管理 (Stateful Client)
- 保管場所: ブラウザのメモリ + サーバーのDB。
- リスク: 通信エラーやコードのバグで「画面と中身」が食い違う。
- 開発負荷: 常に同期を意識したコード(スナックバーやリトライ処理)が必要。
集中管理 (Stateless Client / HTMX)
- 保管場所: サーバーのDBただ一つ。
- リスク: サーバーに問い合わせる必要があるが、不一致(矛盾)は物理的に起こりえない。
- 開発負荷: プログラムを一箇所(サーバー)に書くだけで済む。テストも非常に楽。
まとめ:初心者のための「安心感」の設計
状態管理をサーバーに集約させることは、開発者にとって「夜、ぐっすり眠れるようになる」ことを意味します。
- 不一致に怯えない: 「画面に嘘が表示されているかも」という不安から解放されます。
- コードを二度書かない: ブラウザ側のロジックと、サーバー側のロジックを両方書く手間が無くなります。
- シンプルさは力: 「State(状態)」という言葉を聞いて身構える必要はありません。HTMLが届く、表示する。ただそれだけのことです。
「真実は一つ(SSOT: Single Source of Truth)」という格言を具現化したのが、HTMXの設計理論です。この安心感の上に立って、最後のステップとして「SPAという概念をいかにシンプルに捉え直すか」(010. SPA否定ではなく簡略化)について考えていきましょう。