コース一覧
フロントデバッグ道場 呪われたウィジェット供養の10問
黄色い警告を消せ

フロントデバッグ道場 呪われたウィジェット供養の10問

React で書かれた壊れたウィジェットを、自分の手で直していく演習専用コースです。解説はありません。症状と完成条件だけを読み、原因を突き止めて直します。手が止まったときのために、方針・調べ方・部分解の3段階のヒントを各問に用意しています。他の道場と違い、白紙からではなく「動いているように見えて壊れているコード」から始まります。関数名のタイポ、フォームの既定動作、key 忘れ、プロパティ名の取り違えといった見つけやすい呪いから始まり、state の直接変更、useEffect の無限ループ、set 直後の古い値、非同期応答の追い越しといった再現しにくい呪いへ進み、最後は5つの呪いが同時にかかったウィジェットを1つずつ払います。1問15分から45分、全10問で約4.5時間です。React入門を終えて「エラーが出ると手が止まる」と感じている方に向いています。

1
初段
01. ボタンが反応しない15分
02. 送信すると消える15分
03. 黄色い警告を消せ20分
04. undefined が出る20分
2
中段
01. 数字が増えない25分
02. 無限ループを止めろ25分
03. 一つ前の値が表示される30分
04. 検索結果が入れ替わる30分
3
師範
01. 赤いエラーを読んで直せ35分
02. 総合 5つの呪いを全部払え45分

黄色い警告を消せ

初段 / 目安 20分

琥珀さんがコンソールを指さします。「動いてはいるんだけど、コンソールが黄色いんだ……『unique "key" prop』って。気持ち悪いから成仏させて」。

今回の呪いは、画面には出ません。店舗の一覧はちゃんと並んでいるし、押しても壊れません。それでもコンソールには黄色い警告が出ています。動いているのに警告が出ている、という状態です。

出ているのは Warning: Each child in a list should have a unique "key" prop. という警告です。配列から map で要素を並べたとき、React はそれぞれの要素に key を求めます。書いていないと、この警告が出ます。

なぜ求められるのかというと、React は画面を描き直すとき 前回と今回のリストを見比べて、差分だけを直そうとする からです。key があれば「この行は前回のあの行と同じものだ」と分かるので、並べ替えや途中への差し込みが起きても中身がずれません。key が無いと、React は並んだ順番だけで見比べます。順番が変わらないうちは平気ですが、途中に1件足したり並べ替えたりした瞬間に、入力欄の中身やチェック状態が別の行にくっついていく、という気味の悪い事故が起きます。

警告というのは「いつか事故る」の予言です。黄色いうちに供養しておくのが正しい態度です。

key に渡すのは、その要素を一意に指せる値 です。データにID があるならそれが最善です。今回の店舗データには id が付いているので、それを使ってください。配列の添字 (index) でも警告そのものは消えますが、並べ替えや削除があると添字は付け替わるので、ID がある場面でわざわざ添字を使う理由はありません。

key は map の中で いちばん外側に返す要素 に付けます。中の子要素に付けても警告は消えません。

完成条件

  • map で並べている要素に key を付け、コンソールの警告を消す
  • key には店舗データの id を使う
  • 表示されている一覧の中身は今のまま変えない

進め方

初期コードは店舗の配列を map で li にして並べています。書き足すのは1か所だけです。表示は今も正しく出ているので、見た目を変える必要はありません。

直したあとは、コンソールに黄色い行が残っていないことを確かめてください。この問題の合格条件には「key= を書いたか」をソースで見るものが入っています。案内のコメントは判定の前に取り除かれるので、コメントに書いても通りません。

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

供養が済むと、師範が言います。「警告は『いつか事故る』の予言だ。黄色いうちに供養したのは正しい」。

ヒント

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

①方針 警告は「配列から並べた要素それぞれに、見分けるための印を付けてほしい」という意味です。並べているのは map なので、直すのは map の中の1か所だけです。表示は変えなくて構いません。

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

できているか

  • map で返す要素に key を書いている
  • key に店舗データの id を渡している
  • 店舗が4件並んだままになっている
  • 2件目の店舗名が正しく出ている
エディタを読み込んでいます