We want to hear from you!Take our 2021 Community Survey!
このサイトの更新は終了しました。ja.react.dev へ

非制御コンポーネント

この記事は古くなっており、今後更新されません。新しい React 日本語ドキュメントである ja.react.dev をご利用ください。

以下の新しいドキュメントで最新の React の使い方がライブサンプル付きで学べます。

ほとんどの場合では、フォームの実装には制御されたコンポーネント (controlled component) を使用することをお勧めしています。制御されたコンポーネントでは、フォームのデータは React コンポーネントが扱います。非制御コンポーネント (uncontrolled component) はその代替となるものであり、フォームデータを DOM 自身が扱います。

非制御コンポーネントを記述するには、各 state の更新に対してイベントハンドラを書く代わりに、ref を使用して DOM からフォームの値を取得します。

例えば、以下のコードは非制御コンポーネントで 1 つの名前を受け取ります:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.input = React.createRef();  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.input.current.value);    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={this.input} />        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

CodePen で試す

非制御コンポーネントでは DOM に信頼できる情報源 (source of truth) を保持するため、使用すれば React と非 React のコードの統合が簡単になることがあります。汚くても構わないので速く記述したいと思うなら少しだけコード量も減らせます。そうでなければ、通常の制御されたコンポーネントを使用するべきです。

特定の状況に対してどちらのタイプのコンポーネントを使用すれば良いかまだはっきりしない場合は、制御された入力 vs 非制御入力の記事が参考になるでしょう。

デフォルト値

React のレンダーのライフサイクルでは、フォーム要素の value 属性は DOM の値を上書きします。非制御コンポーネントでは、React に初期値を指定させるが後続の更新処理には関与しないようにしたいことがよくあるでしょう。このケースを扱うために、value の代わりに defaultValue 属性を指定できます。コンポーネントのマウント後に defaultValue 属性の値を変更しても DOM 内の値の更新は引き起こされません。

render() {
  return (
    <form onSubmit={this.handleSubmit}>
      <label>
        Name:
        <input
          defaultValue="Bob"          type="text"
          ref={this.input} />
      </label>
      <input type="submit" value="Submit" />
    </form>
  );
}

同様に、<input type="checkbox"><input type="radio">defaultChecked を、そして <select><textarea>defaultValue をサポートしています。

ファイル input タグ

HTML では、<input type="file"> を利用してユーザに 1 つ以上のファイルをデバイスストレージから選択させ、サーバにアップロードしたり File API を通じて JavaScript で操作したりします。

<input type="file" />

React では、<input type="file" /> は値がユーザだけが設定できるものでありプログラムでは操作できないため、常に非制御コンポーネントです。

ファイルをやり取りするのに File API を使用してください。以下の例では DOM ノードへの ref を作成し submit ハンドラでファイルにアクセスしています。

class FileInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.fileInput = React.createRef();  }
  handleSubmit(event) {
    event.preventDefault();
    alert(
      `Selected file - ${this.fileInput.current.files[0].name}`    );
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Upload file:
          <input type="file" ref={this.fileInput} />        </label>
        <br />
        <button type="submit">Submit</button>
      </form>
    );
  }
}

const root = ReactDOM.createRoot(
  document.getElementById('root')
);
root.render(<FileInput />);

CodePen で試す

Is this page useful?このページを編集する