はじめに
最近、業務上でReact Hook Form
& React Bootstrap
でのコーディングを行うようになりました。
その中で、タイトルの内容について開発チーム内で話題になったのですが、ネット上で調べる限り直接的な回答は得られず。
ドキュメントを読んだり実装を行い、自分なりに結論付けたので、記事として残しておこうと思います。
制御コンポーネント(Controlled component)とは
公式曰く入力フォームの値をReactのstateによって管理するコンポーネントのことを指します。
制御 = React側で値を制御
ということですね。
参考:https://ja.legacy.reactjs.org/docs/forms.html#controlled-components (古いドキュメントだが分かりやすい)
非制御コンポーネント(Uncontrolled component)とは
公式曰く入力フォームの値をDOMよって管理するコンポーネントのことを指します。
非制御 = React側では値を制御しない
といった認識で良いかと思います。
参考:https://ja.legacy.reactjs.org/docs/uncontrolled-components.html
React Bootstrapが提供するコンポーネントは?
結論としては、React Bootstrapが提供するコンポーネントは使い方によって制御コンポーネントにも非制御コンポーネントにもなりうると言うのが正しいのではないかと思います。
試しにReact BootstrapのForm.Controlで実装してみました。
制御コンポーネント的な使い方
React Bootstrapのドキュメント読んだ印象として、基本的にはReact Bootstrapのコンポーネントは制御的に扱うことを想定していそうです。
以下の例では、stateで値を管理し、onChangeで値の変更を行っています。
import { Form } from 'react-bootstrap';
...
export const TestComponent = () => {
const [testValue, setTestValue] = useState('');
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
setTestValue(event.target.value);
};
const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
// stateで管理していた値を取得
console.log("testValue", testValue);
};
return (
<>
<Form onSubmit={handleSubmit}>
<Form.Control
type="text"
value={testValue}
onChange={handleChange}
placeholder="値を入力してください"
/>
<button type="submit">送信</button>
</Form>
</>
);
};
非制御コンポーネント的な使い方
React Bootstrapのコンポーネントには、ref
属性を指定することもできるようです。
ref
属性を指定することで、DOMを参照して値を取得できるようになります。
import { Form } from 'react-bootstrap';
...
export const TestComponent = () => {
const inputRef = useRef<HTMLInputElement | null>(null);
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
// DOMから値を取得
const testValue = inputRef.current?.value;
console.log("testValue", testValue);
};
return (
<>
<Form onSubmit={handleSubmit}>
<Form.Control
type="text"
ref={inputRef}
placeholder="値を入力してください"
/>
<button type="submit">送信</button>
</Form>
</>
);
};
最後に
React Hook Formでは、扱うコンポーネントが制御コンポーネントか非制御コンポーネントかによってバリデーションの実装方法が変わったり、何かと制御/非制御を意識する場面が出てくるかと思います。
簡単な記事でしたが、皆さんの参考になれば幸いです。
以上