コース一覧
React道場 ハレノヒ珈琲をモダン化する10問
肥大部品を分割せよ

React道場 ハレノヒ珈琲をモダン化する10問

React の基本を終えた人が、白紙から部品を組み立てる演習専用コースです。解説はありません。依頼と完成条件だけを読み、自分で設計します。手が止まったときのために、方針・使う構文・部分解の3段階のヒントを各問に用意しています。props を受ける部品から始まり、state、条件付きのクラス、map での描画、絞り込み、制御コンポーネント、入力の検証を経て、最後は部品の分割と注文ウィジェットの完成まで、10問で React の主要な考え方を一巡します。1問15分から45分、全10問で約5時間です。React入門を終えて「写経はできるが白紙からは書けない」と感じている方に向いています。

1
初段
01. MenuCard部品を作れ15分
02. いいねボタン15分
03. ダークモード切替(React版)20分
04. メニュー一覧をmapで描画せよ20分
2
中段
01. カテゴリタブで絞り込め25分
02. 予約フォームを制御せよ25分
03. 入力エラーを表示せよ30分
04. 営業中バッジと時計30分
3
師範
01. 肥大部品を分割せよ35分
02. 総合 注文ウィジェット完成45分

肥大部品を分割せよ

師範 / 目安 35分

奥からカメ師範が出てきて、エディタを指さします。「見ろ、App.jsx が肥えてきた。陽葵は喜んでいるが、次の改修で泣くのはお前だ。部品ツリーに分割せよ」。

今回の初期コードは、動いているコードです。壊れているところはありません。だから直す気になりにくい。それがこの問題の狙いです。

1つのファイルにすべてが入っていると、何が起こるか。メニューの見た目を直したいだけなのに予約フォームのコードを読み飛ばす必要が出ます。誰かと同時に触れば、同じファイルでぶつかります。そして何より、どこからどこまでが1つのまとまりなのか、読んだ人には分からないのです。ファイルを分けるのは、その境界を目に見える形で宣言する作業です。

切り方の目安は、画面を枠で区切ってみることです。今回なら店名の見出し、メニュー一覧、予約フォームの3つ。この単位でファイルを分けます。

分けるときに毎回ぶつかるのが state の置き場所です。原則は1つ、その state を使う部品たち全員の、共通の親に置くことです。予約フォームの中でしか使わない名前の state は、フォームの部品の中に持たせて構いません。逆に、複数の部品が同じ値を見るなら親に上げ、props で配ります。今回はメニューのデータが App にあり、MenuList がそれを受け取る形にします。

書き方はこうです。切り出した側では

JavaScript (JSX)

export default function MenuList({ items }) { ... }

のように export default を付け、使う側では

JavaScript (JSX)

import MenuList from "./MenuList";

と読み込みます。ファイル名と import の綴りが1文字でも違うと「見つかりません」で止まるので、そこだけ気をつけてください。

分割は正解が1つに定まる作業ではありません。3つに切るか4つに切るかで意見が割れます。師範いわく「切り方に正解は一つでない。だが切らないは不正解だ」。

完成条件

  • Header.jsx に店名と紹介文を出す部品を書き、App.jsx から使う
  • MenuList.jsx にメニュー一覧を出す部品を書く。メニューのデータは App.jsx から props で受け取り、map で className が card の要素として並べる
  • ReserveForm.jsx に予約フォームの部品を書く。名前の state はこの部品の中に持ってよい
  • 分割後も動きは変わらない。名前を入れて送ると className が done の要素に名前入りの受付文が出る
  • 3つのファイルはすべて export default で送り出し、App.jsx から import して使う

進め方

一度に3つ動かそうとすると、どこで壊れたか分からなくなります。Header だけを切り出して画面が元通りに出ることを確かめる、そこから MenuList、最後に ReserveForm、の順で進めてください。1つ移すたびに画面を見るのが最短です。

移すときは、切り取ってから貼るのではなく、貼ってから消すほうが安全です。移し先が動いてから元を消せば、途中で画面が真っ白になっても原因がすぐ分かります。

Header.jsx などのファイルは最初から用意してあります。中身は空なので、そこに書いてください。

ヒントは3段階で、①方針、②使う構文、③部分解の順に出ます。1つも開けずに通せたら、その問題は自分のものです。

ヒント

前のヒントを開くと次が開きます。開かずに解けると未開封クリアです

①方針 画面を枠で区切って、見出し・メニュー一覧・予約フォームの3つに分けます。それぞれの枠が返していた JSX を、そのまま別ファイルの部品の戻り値に移すだけです。state はその値を使う部品の中に置いてください。

ヒント 2ヒント 1 を開くと読めます
ヒント 3ヒント 2 を開くと読めます
App.jsx
Header.jsx
MenuList.jsx
ReserveForm.jsx
styles.css
プレビュー

できているか

  • App.jsx が MenuList.jsx を読み込んでいる
  • Header.jsx が部品を送り出している
  • 分割しても見出しとメニュー3件がそのまま出ている
  • 分割しても予約が通り、受付文が出る
エディタを読み込んでいます