複数の入力

入力欄が増えても考え方は同じ

お問い合わせフォームには、名前のほかに「ご用件」の選択肢と「本文」の欄が要ります。増えるのは欄の数だけで、やることは前回と変わりません。欄 1 つにつき state 1 つ、value と onChange を 1 組、これを繰り返します。

const [name, setName] = useState(""); const [kind, setKind] = useState("仕事のご依頼"); const [body, setBody] = useState("");

textarea は中身を value で渡す

素の HTML では、textarea の初期値を開始タグと終了タグのあいだに書きました。React ではそう書きません。input と同じく value を使います。

<textarea id="body" value={body} onChange={(e) => setBody(e.target.value)} />

書き方をそろえたのは React の設計上の判断です。おかげで input でも textarea でも、覚えることは value と onChange の 1 組だけで済みます。

select も selected ではなく value

素の HTML では、選ばれている項目に selected を付けました。React では select 自体に value を持たせ、その値と一致する option が選択状態になります。

<select id="kind" value={kind} onChange={(e) => setKind(e.target.value)}> <option value="仕事のご依頼">仕事のご依頼</option> <option value="勉強会のお誘い">勉強会のお誘い</option> <option value="その他">その他</option> </select>

選ばれるのは option の value なので、state の初期値も option のどれかの value と同じ文字列にします。ここがずれていると、最初は何も選ばれていない状態で表示されます。

変更の受け取り方は 3 つとも同じ

input でも textarea でも select でも、onChange のハンドラで見るのは e.target.value です。チェックボックスだけは例外で、こちらは e.target.checked を見ます。真偽値だからです。

つまずきどころ

  • textarea を <textarea>{body}</textarea> と書くと React が警告を出します。value で渡します
  • option 側に selected を書くと警告になります。select の value で決めます
  • state を 1 つにまとめてオブジェクトで持つやり方もありますが、まずは欄ごとに分けるほうが読みやすいです

演習

ご用件の選択と本文の欄を、state とつなぎます。

ヒント

App.jsx
App.jsx
プレビュー

できているか

  • 本文の入力欄が画面にある
  • ご用件を「勉強会のお誘い」に変えるとまとめ行に反映される
  • 本文を入力するとまとめ行に本文が出る
  • お名前を入力するとまとめ行に3つとも並ぶ