Controlled vs Uncontrolled — フォーム入力の取り扱い
このトピックを終えると
Reactでinputを扱う2つの方法の違いを理解し、状況に応じて適切な方法を選択できるようになります。
HTMLの基本的な動作
HTMLのinputは、自身で値を管理します。
<input type="text" />ユーザーが入力すると、input自体が値を保存します。JavaScriptが関与しなくても動作します。
Reactでは、この値をReactが管理するか、input自身に管理させるかを選択します。
Controlled: Reactが管理
function SearchBox() {
const [query, setQuery] = useState("");
return (
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
/>
);
}valueをstateに指定し、onChangeでstateを更新します。ユーザーがタイピングするたびに:
onChangeイベントが発生setQueryでstateが変更- 再レンダリング
- inputに新しい値が反映
Reactがinputの値を制御します。そのため、"Controlled"と呼ばれます。
利点:入力値に対する完全な制御。リアルタイムのバリデーション、入力制限、フォーマットが可能です。
function PhoneInput() {
const [phone, setPhone] = useState("");
const handleChange = (e) => {
const cleaned = e.target.value.replace(/\D/g, "");
if (cleaned.length <= 11) {
setPhone(cleaned);
}
};
return <input value={phone} onChange={handleChange} />;
}数字のみ入力でき、11文字を超えることはできません。
Uncontrolled: DOMが管理
function FileUpload() {
const inputRef = useRef(null);
const handleSubmit = () => {
const file = inputRef.current.files[0];
console.log(file.name);
};
return (
<div>
<input type="file" ref={inputRef} />
<button onClick={handleSubmit}>Upload</button>
</div>
);
}refを使ってDOM要素に直接アクセスし、値を読み取ります。React stateを経由しません。input自身が値を管理し、必要に応じて読み取ります。
ファイルinputはセキュリティ上の理由から、valueをプログラムで設定することができないため、uncontrolledでしか使用できません。
選択基準
Controlledを使用する場合:
- リアルタイムのバリデーション(メールアドレス形式の確認、文字数制限)
- 入力値に応じて異なるUIを即座に表示する必要がある場合
- 複数のinputの値を1つのstateで管理する場合
- フォームを送信する前にデータを加工する必要がある場合
Uncontrolledを使用する場合:
- ファイルアップロード
- 値を送信時にのみ読み取る場合
- 既存のHTMLフォームをReactに移行する場合
ほとんどの場合、Controlledがデフォルトの選択肢です。Reactの公式ドキュメントもControlledを推奨しています。
重要なポイント
Controlledコンポーネントは、React stateがinputの値を管理します。リアルタイムの制御が可能です。 Uncontrolledコンポーネントは、DOMが値を管理し、
refを使って必要に応じて読み取ります。 ほとんどのフォームでは、Controlledがデフォルトの選択肢です。