考える手順
Hotwireの考え方を理解しやすくするために、React, jQuery等と比較して紹介します。
下記のようなUIを作るときのHotwireのアプローチを、Reactと比べながら解説します。
Hotwireの場合は以下のように考えます。
a
タグにしますa
タグのhref
属性の/users/2/user_profile
は#user-profile
に埋め込むべきHTMLを返してくれるサーバのエンドポイントですa
タグのdata-turbo-frame
は、サーバから帰ってきたHTMLをどこに埋め込むかを指定していますReactの場合は以下のように考えます。
onclick
イベントハンドラを繋げて、クリックしたらselectedUser
ステートを2に更新しますUserProfile
コンポーネントのpropsにステートselectedUser=2
を渡し、UserProfile
コンポーネントはselectedUser=2
に該当するデータをサーバに要求しますUser.id=2
に該当するUserの情報をJSONで返しますuserProfile
ステートにセットされますuserProfile
ステートを使って、virtual DOMを作成し、新しいUserProfile
コンポーネントのHTMLを作りますUserProfile
のHTMLと、現在ブラウザに表示されているものを比較して、差分を取り、差分を現在のブラウザ画面に当てはめますselectedUser
のステートを設定して、間接的にUserProfile
コンポーネントがサーバにデータを取りに行くようにします#user-profile
にすぐに埋め込みますuserProfile
ステートに設定すると、間接的に新しい情報が表示されるようになりますHotwireは目標に対して直接的に処理をしています。一方でReactはまずステートに着目して、これを変更した結果として間接的に UIが更新されるような仕掛けを用意しています。直接的に画面を操作することは許されず、常にステート経由で間接的にUIを更新する仕組みです。
少なくともシンプルなケースにおいては直接的なものがわかりやすいでしょう。一方で複雑になってくれば、間接的にそして宣言的にUIを記述することの意義が出てきます。
参考までにjQueryのやり方を紹介します。
/users/2/user_profile
にリクエストが飛ぶようにしますuser-profile
に埋め込まれるようにしますjQueryのやり方はHotwireとよく似ていて、直接的です。やはりシンプルでわかりやすいです。
jQueryに対する批判として多かったのは、単純なケースではシンプルである一方で、複雑になるとすぐに混乱してスパゲッティーコード化するというものでした。 一方でHotwireはHTML属性を宣言的に使用しますので、UI/UXが複雑になっても混乱しにくくなっています。
Hotwireと似たアプローチであり、どのバックエンドでも使用できる技術としてはHTMXやAlpine.jsがあります。特にHTMXは注目されていて、Astro, Python, Java Spring, Honoと組み合わせた例がしばしば報告されています。
私も十分にHTMXを試していないのではっきりしたことは言えませんが、Hotwireと比較した場合、大きな違いはHTML属性をどれだけ用意しているかだと感じています。
Hotwireは37signalsの製品で誕生し、実際の製品の複雑なUIでもわかりやすく作るために生まれた技術です。多くの箇所は出来合いのHTML属性だけで対応しますが、必要に応じてカスタムJavaScriptを書くことも重視しています。現実の複雑なプロダクトのエッジケースに対応するため、比較的すぐにJavaScriptを書きます。要するにHotwireは非常に現実主義的です。
それに対して、HTMXはHTML属性中心の宣言的アプローチをより深く追求した、より野心的で学術的なものだと私は感じています。