React · LEARN AT YOUR OWN PACE今日も、一歩ずつ。

LESSON 06 · 約30分

フォームの入力を、状態につなぐ

ラベル付きの入力と送信を作り、空欄・エラー・結果の状態を扱います。

コードを試す前に

01のVite reactテンプレート(JavaScript/JSX)を使います。特記のないApp.jsxは、そのレッスンだけで動く独立した例です。例同士を連結しないでください。

短い学習用の例です。各App.jsxは独立した例で、順に追記して一つの完成品にする形式ではありません。ファイル名、依存関係、未定義部分の前提は注記に記載します。問題内の抜粋や空欄は、そのまま実行するための完成コードではありません。

開発環境の準備を確認する →

このレッスンでわかること

  • controlled inputのvalueとonChangeを組み合わせられる
  • フォームの送信と入力検証を実装できる

入力の値を誰が持つか

value={title}とonChangeでstateを更新する入力はcontrolled inputです。Reactのstateが表示値の基準になります。文字入力は空文字で初期化し、途中からundefinedに切り替えません。チェックボックスはvalueではなくcheckedとevent.target.checkedを組み合わせます。

送信はformで受ける

formのonSubmitなら、送信ボタンと入力中のEnterを同じ処理にできます。このローカル演習ではpreventDefaultで通常のページ移動を止め、trim後の空欄を検証します。入力中の値と、送信後の結果を別にすると、編集中なのか確定済みなのかが伝わります。

ラベルとエラーも画面の一部

placeholderだけをラベルの代わりにしません。labelのhtmlForとinputのidを対応させます。エラーがある場合は文章で理由を示し、aria-describedbyで関連付けます。実際にサーバーへ送るアプリでは、ブラウザーでの検証に加えてサーバー側でも入力と権限を検証します。

学習テーマを受け付ける

src/App.jsx
import { useState } from 'react';

export default function App() {
  const [title, setTitle] = useState('');
  const [error, setError] = useState('');
  const [result, setResult] = useState('');

  function handleSubmit(event) {
    event.preventDefault();
    const value = title.trim();
    if (!value) {
      setError('学習テーマを入力してください。');
      setResult('');
      return;
    }
    setError('');
    setResult(`「${value}」を練習します。`);
    setTitle('');
  }

  return (
    <main>
      <h1>テーマを決める</h1>
      <form onSubmit={handleSubmit} noValidate>
        <label htmlFor="topic">学習テーマ</label>
        <input id="topic" value={title}
          onChange={event => { setTitle(event.target.value); setError(''); }}
          aria-invalid={Boolean(error)}
          aria-describedby={error ? 'topic-error' : undefined} />
        {error && <p id="topic-error" role="alert">{error}</p>}
        <button type="submit">決定する</button>
      </form>
      <p role="status">{result}</p>
    </main>
  );
}

noValidateはこの例で独自の検証メッセージを学ぶためです。IDはAppが1つだけ表示される前提。送信は端末内の状態更新だけで、通信や永続保存はしません。

TRY IT YOURSELF

入力と送信を確かめる

  1. 空文字とスペースだけの入力を送信し、理由が出るか確かめる
  2. 正しいテーマをEnterで送信し、結果と入力欄のリセットを確認する
  3. 20文字以内という条件を追加し、入力欄の近くへ条件を表示する
  4. マウスを使わずTab・文字入力・Enterで一連の操作を試す

できたらOK:空欄を受け付けず、ラベル付き入力をEnterで送信でき、成功とエラーが区別できる

QUICK CHECK

理解を確かめよう

controlledな文字入力で、value={title}と組み合わせる基本の処理はどれ?

公式資料でもう少し詳しく

ここまで読めたら、ひとつ前進。