ここではApple Storeを模写しながら、Turbo, Stimulusのステートの使い方を考えてみます。Apple Storeの場合は以下のようになっています
- オプションを選択すると、それに応じてリアルタイムで表示価格が変更されます
- 合計金額
- 各オプションの隣に表示される合計価格 (例えば現在のモデルのRAMを1TBに変更した時に合計はいくらになるか)
- カラーオプションを選択すると、それに応じて画像が切り替わります
- 前のオプションを選択するまで、次のオプションは選択不可能状態です。オプションを選択すると、次のオプションは選択可能に切り替わります
また、オプション選択をしてもネットワーク通信は発生しません。価格更新を含めてすべてブラウザだけでやっています。何も考えないとコードがスパゲッティになりやすいぐらいの複雑さです。
比較的ステート管理が複雑な例ではないかと思いますので、これを使ってHotwireによるステート管理を議論したいと思います。以下の方法を検討します。
- サーバでステート管理する場合: オプションを選択するたびにサーバと通信を行い、レスポンスとして更新された画面を受け取ります。サーバ通信が発生するにも関わらず、Turboで良好なUI/UXを保つ方法を確認します
- ブラウザでStimulusを使ってステート管理する場合: 実際のApple Storeと同様にすべてブラウザで価格等の更新をします。複雑なステートをどのようにStimulusで管理し、画面の複数箇所を効率的に(コードをスパゲッティにせずに)更新するかを確認します
- Reactを使ってステート管理する場合: 実際のApple StoreはここだけがReactです(他は通常のMPA)。ブラウザだけでステートを管理し、ネットワーク通信せずに画面を更新するのはReactの得意分野です。Hotwireを使った方法と比較し、何が利点なのかを確認します
関連ページで実際に実装してみた例を紹介しました。そこからわかったことを解説します。
- 比較的複雑なステートであっても、Hotwireで問題なく対応できました。ステートをStimulusに持たせ、サーバ通信をしないケースであっても、StimulusのValuesで対応できます
- ステートを画面に反映させるステップに一番大きな違いがありました
- Stimulus サーバ通信なしの場合はブラウザだけでHTMLを何箇所も更新をする必要があります。StimulusはJSXのようなものを用意していませんので、
targetで指定した箇所をそれぞれ更新しなければならず、コードは一直線なので複雑ではありませんが、煩雑になります
- それに対してサーバでERBを各場合やReactでJSXを書く場合は、HTML生成とステートの反映が同時にできます。これはやはり書きやすいです
- いずれのケースでも、ビジネスロジックを
IPhone.jsやIphone.rbなどに持たせることが効果的でした。ここにしっかりロジックを収められれば、サーバでやるか、Stimulusを使うか、Reactを使うかの違いは比較的些細なことに感じられました
- より複雑なステート管理が必要な場合は、各技術の差がもっと広がる可能性があります
- Stimulus ControllerやReactに最初に渡すデータの作成が煩雑になりそうです。かつこれをブラウザ側のコードと整合性を持たせるのに苦労することが危惧されます
- Stimulusのステートを
targetに書き出す箇所が大幅に増えたり、HTMLを大きく変更する必要がある場合は煩雑になりそうです