ここまで作ってきたことりずかんは、こういう形になっています。
src/
├── components/ BirdCard, AddBirdForm
├── pages/ BirdListPage, BirdDetailPage, NotFoundPage
├── hooks/ useBirds, useFavorites
├── types.ts
├── App.tsx
└── main.tsxこれは小〜中規模の定番の形です。ただし正解は1つではないので、この回では判断の基準を扱います。
種類ごと → 機能ごと
最初は種類ごと(components / hooks / pages)で足ります。ファイルが少ないうちは、これがいちばん分かりやすいからです。
破綻するのは、機能が増えたときです。
components/
├── BirdCard.tsx
├── BirdFilter.tsx
├── AddBirdForm.tsx
├── UserAvatar.tsx
├── UserSettingsForm.tsx
├── NotificationBell.tsx
└── …(30ファイル)「鳥の機能を直したい」ときに、30個の中から関係するものを探すことになります。そこで機能ごとにまとめ直します。
src/
├── features/
│ ├── birds/
│ │ ├── BirdCard.tsx
│ │ ├── AddBirdForm.tsx
│ │ ├── useBirds.ts
│ │ └── types.ts
│ └── user/
│ ├── UserAvatar.tsx
│ └── useUser.ts
├── shared/ ← 機能をまたいで使う部品(Button, Modal など)
├── pages/
└── App.tsxコンポーネントを分ける基準
行数ではありません。役割が2つ以上になったら分けます。
| 分けどきのサイン | 例 |
|---|---|
| 役割が2つ以上ある | 1つのファイルがデータ取得も一覧もフォームも持っている |
| 名前が付けられる | 「これは検索ボックスだ」と言えるまとまり |
| 同じ形を2回書いた | コピペしたくなった瞬間 |
| 中で状態を持ち始めた | 開閉・選択などを自分で持つようになった |
逆に、分けないほうがいい場合もあります。
- 1回しか使わない数行——ファイルを開く手間のほうが大きい
- 親子でpropsを10個受け渡す——分け方が間違っているサイン。まとまりを見直す
命名の実務的な線
こまかい話ですが、レビューで指摘されるのはたいていここです。
| 対象 | 慣習 |
|---|---|
| コンポーネントのファイル | PascalCase.tsx(BirdCard.tsx) |
| フック | useXxx.ts(useBirds.ts) |
| その他の関数・定数 | camelCase.ts |
| イベント系のprops | onXxx(onToggleFavorite) |
| 真偽値 | isXxx / hasXxx(isFavorite) |
| ハンドラ関数 | handleXxx(handleSubmit) |
on〜は「渡されるもの」、handle〜は「実装するもの」という使い分けが定着しています。守るとコードを読む人の予測が当たるようになります。
LintとFormatterは入れておく
チーム開発では前提と考えてよいものです。
- Formatter(Prettierなど)——書式を自動でそろえる。インデントや引用符の指摘がレビューから消える
- Lint(ESLint / Oxlintなど)——バグになりやすい書き方を検出する。Hooksのルール違反もここで拾える
ViteのreactテンプレートにはOxlintが最初から入っています(npm run lint)。ESLintを使いたい場合は、作るときに--eslintを付けるか、あとから差しかえます。
レビューで実際に指摘されること
最後に、新人のPRでよく付く指摘を挙げておきます。ここまでのコースで全部扱った内容です。
| 指摘 | このコースのどこか |
|---|---|
keyにindexを使っている | listsの回 |
| 計算できる値をstateで持っている | eventsの回 |
useEffectでやらなくていいことをしている | effectの回 |
| propsが多すぎる/関係ないものが混ざっている | conditionalの回 |
| 状態の置き場所が高すぎる/低すぎる | lifting-stateの回 |
anyで押し切っている | typescript-practiceの回 |
| ボタンにラベルが無い(読み上げできない) | stateの回 |
「動くけれど指摘される」ものの正体は、ほとんどが置き場所の問題です。
このレッスンのまとめ
- 種類ごとで始めて、つらくなったら機能ごと(
features/)へ。最初から切らない - 機能ごとの強みは変更が1フォルダで完結すること。消すときも楽
- 分けどきは行数ではなく役割が2つ以上になったとき
- 細かく割りすぎない。1画面を読むのに5ファイル開くのは分けすぎ
- 命名は
PascalCase.tsx/useXxx/onXxx(渡す) /handleXxx(実装する) - LintとFormatterは入れる——書式の指摘をレビューから消すため
- レビューの指摘の多くは「置き場所」の問題。このコースで扱ってきたものばかり
次は、古いReactのコードを読む回です。既存の案件に入ると必ず当たります。