Более чистый способ создания React Forms

Формы в современном Интернете повсюду.
С Reactjs мы все тратим много времени на связывание входов и контейнеров, передачу реквизитов, получение значений разными способами: ввод текста, флажки, выбор.
Мы пытаемся понять, когда пользователь прекратить редактирование, чтобы вызвать событие «автосохранения».
Мы переписываем форму или создаем внутри нее «операторы if» для каждого небольшого изменения в поведении.

react-distribution-forms - это библиотека, которая позволяет писать React Forms самым простым и понятным способом.

Https://github.com/StayDistributed/react-distributed-forms

Живая демонстрация

На основе контекста (без повторяющихся реквизитов…)

Вы можете настроить поведение полей, поместив их в другую ‹Form› (а затем в другой контекст).

В следующем примере компонент ‹NameInfo /› будет подключен к разным формам Developer и UIDesigner, без передачи реквизитов, с внутренним использованием Context.

import { Form, Input } from 'react-distributed-forms';
const NameInfo = () => (
  <div className="NameInfo">
    <Input name="first_name" />
    <Input name="last_name" />
  </div>
);
const Developer = () => (
  <Form onFieldChange={({ name, value }) => {}}>
    <NameInfo />
    <Select name="programming_languages" multiple>
      <option>Java</option>
      <option>C</option>
      <option>Python</option>
      <option>Go</option>
    </Select>
  </Form>
);
const UIDesigner = () => (
  <Form onFieldDidChanged={({ name, value }) => {}}>
    <NameInfo />
    <Select name="tools">
      <option>Illustrator</option>
      <option>Photoshop</option>
      <option>Sketch</option>
    </Select>
  </Form>
);

Агностик стиля

Вы можете использовать CSS, Sass, Less, Stylus, CSS-in-JS,…
react -formed-forms отображать только компоненты HTML, без идентификаторов, классов или встроенных стилей.

<Input />
// <input type="text"></input>
----------
<Form values={{ username: "Hero2018" }}>
  <Input name="username" />
</Form>
// <input type="text" name="username" value="Hero2018"></input
----------
<Form>
  <Input name="username" />
  <Select name="genre">
    <option value="m">Male</option>
    <option value="f">Female</option>
  </Select>
</Form>

// <input type="text" name="username"></input>
// <select name="genre">
//   <option value="m">Male</option>
//   <option value="f">Female</option>
// </select>

Двусторонняя привязка данных

Если вы поместите ‹Form› внутри компонента React с состоянием, вы можете привязать значения формы к этому состоянию:

// binding={this} binds Form values to SomeComponent state
class SomeComponent extends React.Component {
  state = {
    first_name: "George"
  };

  render() {
    return (
      <Form binding={this}>
        <Input name="first_name" />
      </Form>
    );
  }
}

Вложенные формы

Вы можете поместить форму внутри формы, почему?
Потому что вы можете разделить свои формы на более мелкие части и прослушивать только изменения подмножества полей, в то время как из родительской формы вы слушаете ВСЕ изменения полей.

<Form id="parent" onFieldChange={({ name, value }) => {}}>
  <Input name="username" />
  <Select name="genre">
    <option value="m">Male</option>
    <option value="f">Female</option>
  </Select>
  <Form id="child" onFieldChange={({ name, value }) => {}}>
    <label>Privacy Agreement</label>
    <Input type="checkbox" name="privacy" />
  </Form>
</Form>

#parent onFieldChange прослушивает все поля,
#child onFieldChange прослушивает только поле «privacy»

Посмотреть на Github:

Https://github.com/StayDistributed/react-distributed-forms