В большинстве случаев рекомендуется использовать контролируемые компоненты для реализации форм. В управляемом компоненте данные формы обрабатываются компонентом React. Альтернативой являются неконтролируемые компоненты, где данные формы обрабатываются самой DOM.

Чтобы написать неконтролируемый компонент, вместо написания обработчика событий для каждого обновления состояния, вы можете использовать ref для получения значений формы из DOM.

Например, этот код принимает одно имя в неконтролируемом компоненте:

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

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

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

Поскольку неконтролируемый компонент сохраняет источник правды в DOM, иногда проще интегрировать код React и non-React при использовании неконтролируемых компонентов. Он также может быть немного меньше кода, если вы хотите быть быстрым и грязным. В противном случае вы должны обычно использовать контролируемые компоненты.

Значения по умолчанию

В жизненном цикле рендеринга value атрибута атрибут элементов формы переопределит значение в DOM. При неконтролируемом компоненте вы часто хотите, чтобы React указывал начальное значение, но оставляйте последующие обновления неконтролируемыми. Для обработки этого случая вы можете указать defaultValue атрибут вместо value.

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

Точно так же <input type="checkbox"> и <input type="radio"> поддержка defaultChecked, <select> и <textarea> поддержка defaultValue.

Тег ввода файла

В HTML <input type="file"> позволяет пользователю выбрать один или несколько файлов из своего хранилища устройств для загрузки на сервер или манипулировать JavaScript через File API.

<input type="file" />

В React <input type="file" /> всегда является неконтролируемым компонентом, потому что его значение может быть задано пользователем, а не программно.

Вы должны использовать File API для взаимодействия с файлами. В следующем примере показано, как создать ссылку на узел DOM для доступа к файлам (-ам) в обработчике отправки:

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

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

ReactDOM.render(
  <FileInput />,
  document.getElementById('root')
);