バリデーション

入力の確認も state の仕事

名前が空のまま送信されたら、送らずに「入力してください」と伝えたい。この入力チェックを バリデーション と呼びます。

JavaScript 入門では、エラー文の p 要素を textContent で書きかえていました。React ではその書きかえをしません。画面は state から作るので、エラー文も state に持ちます。state が変われば画面がついてきます。

const [error, setError] = useState("");

送信のハンドラで分岐する

function handleSubmit(e) { e.preventDefault(); if (name === "" || body === "") { setError("お名前と本文を入力してください"); setSent(""); return; } setError(""); setSent(name + " さんから受け取りました"); }

見どころが 2 つあります。

1 つめは return です。エラーを立てたらそこで関数を終わらせます。書き忘れると、エラーを出したうえで送信も続きます。

2 つめは、通ったときに setError("") でエラーを消していることです。一度出したエラー文は、消す処理を書かないかぎり残り続けます。state は自分で片付けないと元に戻りません。

エラー文を画面に出す

<p id="error">{error}</p>

error が空文字のあいだは中身の無い p が置かれるだけで、何も見えません。値が入ったときだけ文字が現れます。もっと丁寧にやるなら、赤字にしたり、エラーのときだけ要素ごと出したりします。条件で要素を出し分ける書き方は第 6 章で扱います。

空白だけの入力

name === "" だけだと、スペースを 1 つ打っただけで通ってしまいます。前後の空白を落としてから比べると防げます。

if (name.trim() === "") { ... }

つまずきどころ

  • チェックは preventDefault() のあとに書きます。順番が逆だと、エラーでも送信が走ります
  • 送信が通ったときにエラーを消し忘れると、成功してもエラー文が残ります
  • required 属性だけに頼らないでください。ブラウザごとに見た目が違い、思ったところで止まりません

演習

未入力のまま送信されたら、エラー文を出すようにします。

ヒント

App.jsx
App.jsx
プレビュー

できているか

  • 何も入れずに送信するとエラー文が出る
  • 名前だけ入れて送信しても、本文が空ならエラーのままになる
  • 両方そろえて送信すると結果が出る
  • 本文を消して送信し直すと、また未入力のエラーになる