コース一覧
フロントデバッグ道場 呪われたウィジェット供養の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分

送信すると消える

初段 / 目安 15分

琥珀さんが眉を寄せています。「アンケート、送信ボタンを押すと画面が真っ白に戻って回答が消えるんだ。お客さんキレ気味」。

初期コードのアンケートは、名前を入れて送信ボタンを押す作りです。押すと、入力欄が空に戻り、完了メッセージも出ません。書いた人の側からすると「何も起きなかった」ように見えますが、実際には 画面がまるごと読み込み直されています。

これは form の既定の動作です。HTML のフォームは、送信されるとブラウザが入力内容をサーバーへ送り、返ってきたページを表示し直します。React が state に持っていた値も、そこで全部消えます。サーバーへ送る作りになっていなければ、同じページを読み直すだけで、結果として「何もなかったこと」になります。

これを止めるのが e.preventDefault() です。送信の処理は onSubmit で受け取り、その関数の第一引数にイベントが渡ってきます。処理の先頭で e.preventDefault() を呼べば、ブラウザの既定の動作 (ページの読み込み直し) をやめさせられます。既定の動作を止めたうえで、自分で「送信されたあとにやりたいこと」を書く、というのがフォームの基本の形です。

止めるだけでは供養は終わりません。今回は送信のあとに 完了メッセージを画面へ出す ところまでが依頼です。送ったかどうかを state に持ち、送信されたら true にして、その値によってメッセージを出し分けます。

もう1つ気をつけたいのが、送信を受ける場所です。ボタンの onClick で受けると、Enter キーで送信されたときに素通りしてしまいます。受けるのは form の onSubmit です。

完成条件

  • 送信してもページが読み込み直されないよう、e.preventDefault() で既定の動作を止める
  • 送信したら className が done の要素に「送信しました」と出す
  • 送信は form の onSubmit で受ける

進め方

初期コードには入力欄と送信ボタン、そして送信済みかどうかを持つ state がすでに置いてあります。呪われているのは、送信を受ける処理が 既定の動作を止めていない ことと、その先の処理が書かれていないことです。

直したら、名前を入れて送信し、入力した文字が残ったまま完了メッセージが出ることを目で確かめてください。入力が消えていたら、まだページが読み込み直されています。

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

供養が済むと、琥珀さんはこう言います。「回答が、消えない……!(感涙)」。

ヒント

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

①方針 押しても何も起きないように見えるのは、ページがまるごと読み込み直されているからです。まず form の既定の動作を止め、そのうえで「送信されたら何をするか」を自分で書きます。

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

できているか

  • 送信の処理で preventDefault を呼び、ページの読み込み直しを止めている
  • 名前を入れて送信すると「送信しました」が出る
エディタを読み込んでいます