コース一覧
React Routerとアプリ設計
機能別フォルダ

React Routerとアプリ設計

React Router、Routes・Route・Link、URLパラメータ、検索条件、404、見た目と機能の分離、合成、機能別フォルダを扱う全18レッスンのアプリ設計コースです。fleamaを商品一覧・詳細・出品・カート・マイページを持つ複数ページSPAとして完成させます。

1
ルーティング(React Router v7)
01. ルーティング導入15分
02. RoutesとRoute15分
03. 遷移を作る15分
04. URLパラメータ15分
05. 検索条件をURLに15分
06. 404ページ15分
07. つくる - ページ分割完了20分
08. 第7章クイズ15分
2
コンポーネント設計パターン
01. 見た目と機能の分離15分
02. 合成で組み立てる15分
03. 機能別フォルダ10分
04. つくる - 設計リファクタ20分
05. 第8章クイズ15分
3
総合制作
01. 購入フロー20分
02. マイページ20分
03. 仕上げ15分
04. 自由拡張20分
05. 完成と次のステップ10分

機能別フォルダ

種類で置くか、機能で置くか

種類でまとめると、直すたびに散らばる

ファイルが増えてくると、まず思いつくのは種類でまとめる形です。

プレーンテキスト

components/ ItemList.tsx Cart.tsx ItemCard.tsx CartLine.tsx hooks/ useItems.ts useCart.ts types/ item.ts cart.ts

一見きれいですが、仕事のしかたと合っていません。「カートに数量を足す」という1つの用事で、components と hooks と types を行き来することになります。関係のあるファイルほど遠くに置かれる形だからです。

機能でまとめる

fleama を「商品」と「カート」という機能で割ると、こうなります。

プレーンテキスト

features/ items/ ItemList.tsx types.ts cart/ Cart.tsx types.ts components/ Layout.tsx

カートを直すときに開くのは features/cart だけになります。機能ごと消したくなったら、フォルダごと消せます。一緒に変わるものを一緒に置く、というのがこの分け方の考え方です。

features に入れないのは、どの機能のものでもない部品です。Layout やボタンのような枠は components に置きます。迷ったら、その部品が fleama の商品を知っているかどうかで決めます。知っていれば features、知らなければ components です。

import の書き換えが起きる

移すと、呼ぶ側の道のりが変わります。

TypeScript (JSX)

import { ItemList } from "./features/items/ItemList"; import { Cart } from "./features/cart/Cart";

型も機能の持ち物です。商品の Item は features/items/types.ts に置き、カートからもそこを読みます。同じ型を2か所に書くと、片方だけ直して静かに壊れます。

演習

いまの平たい構成を、features の下に機能別に置き直します。

ヒント

features/cart から商品の型を読むときは ../items/types をたどります

合計は lines.reduce((sum, item) => sum + item.price, 0) で出せます

移したあとの App.tsx は ./features/items/ItemList を読む形になります

App.tsx
Cart.tsx
ItemList.tsx
features/cart/Cart.tsx
features/items/ItemList.tsx
features/items/types.ts
types.ts
プレビュー

できているか

  • カードが3枚並んでいる
  • 3枚とも価格が出ている
  • カートが出ている
  • カートに入れると合計が出る
  • App が features/items から一覧を読んでいる
  • App が features/cart からカートを読んでいる
  • App が商品の型を features/items から読んでいる
  • 移した型に status まで入っている
  • 一覧の中身が features/items に移っている
  • 合計の表示が features/cart に入っている
  • カートが商品の型を items から読んでいる
エディタを読み込んでいます