Reactアプリで不要だと感じるもの

ここではReactのアプリにはしばしば見られる一方、Hotwireではそもそも存在しないものをリストアップしました。

  • クライアントサイドルータ: Hotwireではクライアントサイドルータは不要です。同様にInertia.jsもReactではあるもののクライアントサイドルータはありません。仮にSPAであっても、サーバ側のルータ1つで十分です
  • JSON API: JSON APIが必要なのはあくまでもクライアントでDOMをレンダリングするためで、CSRやhydrationの際に必要になるだけです。HotwireはERBでHTMLをレンダリングしますので、JSON APIは不要です
  • Open API (Swagger): HotwireはJSON APIが不要なので、Open APIドキュメントの管理が不要です。存在しないメソッドやDBフィールドをERBから呼び出した場合はno methodエラーになりますので、自動テストで容易に整合性を担保できます。
  • シリアライザ: オブジェクトをシリアライズするのは、ネットワーク越しにデータをやり取りするためです。Hotwireの場合はHTML自身がシリアライズされたデータです。ERBテンプレートそのものをシリアライザと呼んでも良いでしょう。JSONを提供するためのシリアライザを別途用意する必要はありません
  • クライアントサイド認証: 一時期はSPAが認証トークンをlocalStorage等で管理する流れがありました。最近はhttp-only cookieで認証することが主流になりましたが、今でもNext.jsサーバなどで認証をすることが珍しくありません(NextAuthなど)。しかしAPIサーバ(Rails)では必ず認証しますので、そこだけで認証すれば十分です
  • API専用エンドポイント: レガシーのERBフロントエンドを「モダン化」する際に、API専用のエンドポイント(例えば/api/v1/users)を作ることがあります。一方でRailsは1つのコントローラアクションからERBテンプレートとJSONの双方を出力できますので、API専用エンドポイントは不要です。
  • 1ページあたり複数のAPIを叩く: Reactのページを1つ表示するのに複数のAPIを叩くことはかなり一般的です。しかしリクエストウォーターフォールが起こりロード時間が遅くなる上、サーバへの負荷が増大してしまいます。1つのページに必要な情報は全て1つのAPIにまとめてしまった方がページロードは早く、サーバ負荷も減ります
    • 固有のコントローラアクションが増えると開発負荷が増すのではないかという意見も聞きますが、現実問題としてERBページを短期間で数百個作ることも珍しくありませんので、大きな負荷にならないと断言できます。
  • ステートの増大: Reactではステート管理が課題ですが、Hotwireだったら考えなくても良いステートがたくさんあります。例えばローディング状態のステートなどはHotwireがHTML属性に反映させてくれますので、CSSだけでローディング画面が実装できます。もちろんページに表示するデータをステートに保持する必要もありません。
  • APIの不要なデータ: JSON APIではページ専用のエンドポイントではなく、モデル(リソース)単位のAPI設計が好まれる傾向があります。その結果、不要なデータを含めてAPIに載せることが多くなり、場合によってはデータを漏洩してしまう可能性が高まります。さらにこれを細かく制御しようとすると、JSONシリアライザが複雑化します。Hotwire/ERBの場合は画面に表示されるデータしかブラウザに届きません。Hotwireでは表示されるデータのみが送信され、不要なデータは送信されませんので、データ漏洩のリスクは大幅に減ります
  • TypeScriptは意外と安全性を担保してくれません: TypeScriptはあくまでもTypeScriptの中の型安全性しか担保してくれませんし、実行時には消えてしまいます。またJSON APIはカバーしませんので、APIのデータとTypeScriptの型が異なる場合は守ってくれません。TypeScriptよりもむしろRuby ERBの方が型安全性が高くなります
  • E2Eで網羅的にテストすることは辛い: ReactはJavaScriptが必要ですので、ブラウザを使ったE2Eテストを使わないとなかなかテストできません。しかしE2Eテストはflakyさに悩まされますし、エラーが出ても原因の特定が難しくなります。一方でERBならrequest specでほとんど事足ります
  • リアクティブ性はあまり必要ない: ページに表示されているコンテンツのうち、ほとんどは非同期に変更する必要がありません。サーバでレンダーしたままで固定ならば、Reactで使って表示する必要はありません
  • CSSモジュールじゃなくても普通のCSSで十分: Reactコンポーネントでしばしば使用されるCSSモジュールですが、CSSの影響範囲をコンポーネントの中に留めるのは通常のCSSだけで十分ですBEM等を使用して、CSSの構造や命名を工夫するだけで十分です。
  • 過剰なコンポーネント: 小さなUI要素までもコンポーネントになっていることが珍しくありません。CSSを当てているだけのものでもコンポーネントになっているのは過剰に思えます
  • /meをグローバルステートに保存: 多くのReactアプリではログインしているユーザの情報を/meAPIエンドポイントかた提供してグローバルステートに保存しています。しかしサーバ側では各エンドポイントで認証・認可をしますので、その情報は毎回取得しています。全てのエンドポイントに/me情報を提供することはサーバとしては負担ではないので、別途/meエンドポイントを用意する必要はないと考えられます。