赤いエラーを読んで直せ
師範 / 目安 35分
琥珀さんがスマホの画面をこちらに向けます。「営業さんから『画面が真っ赤』ってスクショだけ送られてきた。スタックトレースを読んで、犯人のファイルと行番号を特定してから直してほしいんだ」。
今回のウィジェットは、お店台帳です。開いた瞬間に落ちます。1件も出ません。エラーはこう出ています。
プレーンテキスト
TypeError: Cannot read properties of undefined (reading 'tel')
at ShopCard (App.jsx:31:36)
at ...この道場でいちばん大事な回です。エラー文は犯行声明です。読めば、直す場所はほぼ書いてあります。
順番に読みます。まず1行目、TypeError は「値の型が想定と違う」種類のエラーです。続く Cannot read properties of undefined (reading 'tel') は日本語にするとこうなります。「undefined の中の tel を読もうとした」。つまり なにか.tel と書いた場所で、その なにか が undefined だった、ということです。
次に at ShopCard (App.jsx:31:36) を読みます。これは「App.jsx の31行目36文字目、ShopCard という関数の中で起きた」です。スタックトレースは上にあるものほど現場に近いので、一番上の、自分が書いたファイルを指している行が捜査の出発点です。ライブラリの中を指す行は通り道であって、犯人ではありません。
ここまでで、犯人は「ShopCard の中で .tel を読んでいる行」だと確定しました。そこには shop.contact.tel と書いてあります。.tel の手前は shop.contact なので、undefined だったのは shop.contact です。
最後に、なぜ undefined なのかを見ます。データを目で追うと、3件目のみどり書房に contact が付いていません。移転の届け出中でまだ連絡先が入っていない、実際にありがちな形です。データは直しません。 現実の API はこちらの都合で必ず埋まってはくれないので、欠けていても落ちない画面を作るのがフロント側の仕事です。
守り方は2つ組み合わせます。
1つめは optional chaining です。shop.contact?.tel と書くと、shop.contact が undefined や null のときは、そこで止まって undefined を返します。落ちません。
2つめは 無かったときに何を出すか決めること です。undefined を素通しすると画面に何も出ないか、場合によっては文字として undefined が出ます。問4で琥珀さんが「商店街の恥」と言っていたあれです。値が無いときは「準備中」のような、人が読んで意味の分かる文に置きかえてください。
JavaScript (JSX)
const tel = shop.contact?.tel;
// tel が無ければ「準備中」を出すhours はもう一段深く、shop.contact.hours.open です。contact が無い時点で hours も無いので、hours をいったん変数に受けて、有るときだけ時刻の文を組み立てるのが読みやすい形になります。
完成条件
- 画面が落ちず、
classNameが shop のカードが4枚並ぶ - 連絡先のあるお店は、今までどおり電話番号と営業時間が出る
- 連絡先の無いみどり書房も落ちずに出て、電話と営業時間の欄には準備中であることが分かる文が出る
- 画面のどこにも undefined という文字を出さない
- データ (
SHOPS) は書きかえない
完成の前に、原因を言葉にする
ファイルとして提出する報告書はありませんが、直す前に次の3つを自分の言葉で言えるようにしてください。デバッグで本当に身に付くのはここです。
- どこで落ちたか — ファイル名と行、そしてその中のどの式か
- なぜ落ちたか — どの値が undefined で、なぜ undefined だったのか
- どう直したか — 値が欠けていても落ちない形にした、そのやり方
言えないまま直すと、次に同じ形の呪いが出たときにまた最初から迷います。
進め方
エラーが出ている状態から始めてください。まずエラー文を最後まで読み、行番号のところをエディタで開きます。そこに書いてある式を、左から順に「これは undefined になり得るか」と問い直していくと、犯人の位置が1つに絞れます。
ヒントは3段階で、①方針、②使う構文、③部分解の順に出ます。1つも開けずに通せたら、その問題は自分のものです。
供養が済むと、カメ師範が短く言います。「エラー文は犯行声明だ。全文読む者だけが探偵になれる」。
ヒント
前のヒントを開くと次が開きます。開かずに解けると未開封クリアです