Skip to content

2025年時点のWebアプリ設計(フロントエンド)

This content is a draft and will not be included in production builds.

React Router v7のテンプレートが採用しているレイアウトと似ていたのでフロントエンドのディレクトリ構造ベストプラクティスを参考にする。

このとき、components 以下はなるべく純粋コンポーネントとして実装する。コンポーネントが状態を持つことはありえるが、その場合はContainer-PresentationalパターンのようにPresenterとViewを分離する。

コンポーネントが react-router の機能を利用しているとテストで少々面倒になってしまうが、参照を禁止すると扱いづらくなるので、テストの実装にそれほど慎重にならなくてもいい LinkuseParams 程度なら許容する。しかし Formaction と強く結びつくので、コンポーネントから直接参照するのを避けたい。

コンポーネント内部からはAPIを呼び出さない。APIからデータフェッチが必要な場合は、app/routes 以下に置いてReact Router v7のデータローダやアクションを経由する。こちらもコンポーネントなのだが、components 以下の純粋なコンポーネントと区別が付かないので、便宜上ここではサーバーコンポーネント1と表記する。

実装とテストを近い位置に置く概念はコロケーションと呼ぶが、これはテストに限った話ではない。例えば翻訳テキストやCSSもコンポーネントに閉じるとよい。

また、React Server Componentsで解決できることに「コンポーネントの描画に必要なデータは自身で取得する」があるけれど、これもコロケーションの一種といえる。なので適度な粒度で app/routes にサーバーコンポーネントを作り、サーバーコンポーネント内でReact Router v7のデータローダ等を呼び出すといい。例えばログイン状態を持ったヘッダ等はひとつのサーバーコンポーネントとなるだろう。

2025年時点ではReactの状態管理ライブラリ採用に消極的なので、よほどの理由がなければ標準の useStateuseContext を利用する。

ユーザーのフォーム入力についても、Reactのフォームにおける状態の設計で書いたように既存のライブラリはどれも微妙に好みじゃないので使わないが、制御コンポーネントにするなら@susisu/use-controlled-stateは便利。

純粋なコンポーネントは @testing-library/react@testing-library/user-event でテストを書く。純粋なので、おそらくモック等は不要だろう。

サーバーコンポーネントは複数の要素に分解できる。MSW(Mock Service Worker)とはで書いたがこれを使うといい気がする。

  1. React Router v7用語ではRoute Moduleと呼ぶらしい