Day 3・リスト・条件・フォーム — 実データを画面に出す
制御コンポーネント(フォームの値を React が握る)
input の value を state に結びつけ、onChange で更新する制御コンポーネントの型を身につける。
入力欄の値を React の state で管理する
フォームの入力欄(input など)は、放っておくとブラウザ側が値を持ちます。React ではこれを「state に値を持たせ、input はその state を映すだけ」に変えるのが定番です。こうすると入力値の唯一の正解が state になり、React がフォームを握れます。この形を制御コンポーネントと呼びます。
作り方は2ステップです。1つ目、input の value に state を渡す(表示は常に state に従う)。2つ目、onChange で入力のたびに setState して state を更新する。これで「state → 表示」「入力 → state」が一周し、常に一致します。
import { useState } from "react";
function NameForm() {
const [name, setName] = useState("");
return (
<input
value={name}
onChange={(e) => setName(e.target.value)}
/>
);
}onChange に渡す関数は、イベント e を受け取ります。入力された今の文字列は e.target.value で取れます。これを setName に渡すと state が更新され、再描画で value={name} が新しい値になり、画面に反映されます。
なぜ React に値を握らせるのか
値が state にあると、送信前の入力チェック、他の欄と連動した表示、ボタンの有効・無効の切り替え、入力のリセットなどが、すべて state を見る・書き換えるだけで実現できます。値がブラウザ任せだと「今いくつ入っているか」を毎回取りに行く必要があり、ロジックが散らかります。state に一本化することで扱いやすくなります。
非制御(値をブラウザが持つ)
value を state に結ばず、必要なときに DOM から読み出す
// React は値を把握していない
<input ref={inputRef} />
// 送信時に inputRef.current.value を取りに行く制御(値を React が持つ)
value を state に結び、常に state が唯一の正解
<input
value={name}
onChange={(e) => setName(e.target.value)}
/>フォームの送信も押さえておきます。<form> の onSubmit で送信を受け取りますが、そのままだとブラウザがページを再読み込みしてしまいます。これを止めるのが e.preventDefault() です。止めた上で、state に入っている値を使って処理します。
function SearchForm() {
const [keyword, setKeyword] = useState("");
const handleSubmit = (e) => {
e.preventDefault(); // ページ再読み込みを止める
console.log("検索:", keyword);
};
return (
<form onSubmit={handleSubmit}>
<input
value={keyword}
onChange={(e) => setKeyword(e.target.value)}
/>
<button type="submit">検索</button>
</form>
);
}- state を用意する(useState で入力値を持つ)
- input の value に state を渡す(表示は state に従う)
- onChange で e.target.value を setState して更新する
- 送信は onSubmit で受け、先頭で e.preventDefault() を呼ぶ
value を渡すなら onChange も必ず付ける
value={name} だけ書いて onChange を付けないと、値が state に固定されて何を打っても変わらない「読み取り専用」になり、React が警告します。制御コンポーネントでは value と onChange は必ずセットにします。
AIにはこう聞く
「名前とメールを入力する制御コンポーネントのフォームを作って。各 input は value を state に結び、onChange で更新。送信は onSubmit で preventDefault してから値をまとめてログに出して」と伝えると、この章の型どおりのコードが返ります。
読んでも腑に落ちない所は、AIに噛み砕いてもらいましょう。
理解度チェック
答えられれば、面接で説明できる状態に一歩近づきます。
制御コンポーネントで input を作るとき、value と一緒に必ず用意すべきものはどれ?
onChange のハンドラで、入力された今の文字列を取り出すのはどれ?
「非制御コンポーネント」と「制御コンポーネント」の違いを、値をどこが持つかに注目して説明してください。
記述式です。まず自分の言葉で答えを考えてから、模範解答を開いて自己採点してください。