42
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

React Bootstrapが提供するのは制御コンポーネント?非制御コンポーネント?

Posted at

はじめに

最近、業務上で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では、扱うコンポーネントが制御コンポーネントか非制御コンポーネントかによってバリデーションの実装方法が変わったり、何かと制御/非制御を意識する場面が出てくるかと思います。
簡単な記事でしたが、皆さんの参考になれば幸いです。

以上

42
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?