肥大部品を分割せよ
師範 / 目安 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つも開けずに通せたら、その問題は自分のものです。
ヒント
前のヒントを開くと次が開きます。開かずに解けると未開封クリアです