【React】制御コンポーネントと非制御コンポーネント
ReactのFormライブラリに触れる中で「(非) 制御コンポーネント」というワードをよく目にするが、正直定義がよく分かっていなかったので調べた。
結論
- 制御コンポーネント:入力値をReactコンポーネントが保持する
- 非制御コンポーネント:入力値をDOMが保持する
制御コンポーネント
import { type ChangeEvent, useState } from 'react';
export default function ControlledComponent() { const [inputValue, setInputValue] = useState<string>('');
const handleChange = (e: ChangeEvent<HTMLInputElement>) => { setInputValue(e.target.value); };
const handleSubmit = () => { // some logic alert(inputValue); };
return ( <form onSubmit={handleSubmit}> <input type="text" value={inputValue} onChange={handleChange} /> <button type="submit">submit</button> </form> );}
- テキストボックスへの入力値をstateとして保持し、
change
時はstateを更新。submit
時はそのstateを参照する。 - リアクティブな実装に向いている
- 入力する度に実行するバリデーション
- ボタンの
disabled
の制御
- 入力項目が増えた時のstateの管理が大変になる
- 入力する度に再レンダリングされてしまう
非制御コンポーネント
import { useRef } from 'react';
export default function UncontrolledComponent() { const inputRef = useRef<HTMLInputElement | null>(null);
const handleSubmit = () => { // some logic alert(inputRef.current?.value); };
return ( <form onSubmit={handleSubmit}> <input type="text" ref={inputRef} /> <button type="submit">submit</button> </form> );}
- refを対象DOMに設定し、入力値をそのDOMから参照する
- stateの更新による再レンダリングが発生しない
- 1回限りの値の取得に向いている
- 送信時のバリデーション
- 「入力するたびに〜」といった処理には向いていない
参考