Динамическое добавление новых полей в форму с помощью React.js
Недавно я работал над проектом, в котором мне нужно было условно добавлять поля в форму и позволять пользователям добавлять дополнительные поля на лету по мере необходимости. Поначалу это казалось трудным, и, как ленивый разработчик, я погуглил, чтобы узнать, сделал ли кто-нибудь что-то подобное, но я не смог найти ничего, поэтому решил создать его с нуля. Далее следует моя наивная попытка решить только что описанную проблему. Это не идеальное решение, и я хотел бы получить отзывы о том, как сделать его лучше.
Первое, что я сделал, — разбил проблему на более мелкие части, чтобы лучше обдумать ее. Я заметил, что форма должна была делать несколько вещей.
- Создайте новую строку формы.
- Создайте новые поля и добавьте поля в созданную новую строку.
- Добавьте новую строку в исходную форму
- Управляйте состоянием позиций из формы.
Итак, я пошел дальше и создал компоненты, представляющие шаги, описанные выше. Сначала я создал поля, как показано во фрагменте кода ниже.

Следующее, что мне нужно было сделать, это найти способ отслеживать все такие созданные компоненты, чтобы наша форма была заполнена ими. Чтобы решить эту проблему, я создал еще один компонент, который будет действовать как родительский компонент, отслеживая количество созданных линейных элементов и отображая их по мере их создания.

Компонент начинается с одной FormLine. Когда пользователь нажимает кнопку добавления элемента, новый компонент FormLine добавляется в список компонентов, а родительский компонент повторно визуализируется, показывая только что добавленный компонент.
Теперь, когда мы решили первые три проблемы, последняя проблема и, пожалуй, самая интересная — как управлять состоянием позиций из родительского компонента. Первый подход, который я использовал, заключался в том, чтобы отправить состояние всего компонента элемента строки родительскому компоненту, когда пользователь стирает последнее поле ввода в элементе строки. Однако вскоре я обнаружил, что этот подход плохо масштабируется, например, когда пользователь печатает в обоих полях и расплывается, но затем возвращается к первому компоненту ввода и вносит исправление, мы теряем эту информацию.
Чтобы решить эту проблему, я решил, что лучшим подходом здесь будет передача состояния линейного компонента родительскому компоненту при размытии каждого поля. Для этого нам потребуется поддерживать список элементов, который позволяет компоненту добавлять новые элементы в список и изменять элемент в списке. Для этого мне нужно было добавить поле индекса к состоянию каждого элемента строки, чтобы я мог легко находить и изменять его при необходимости. Я модифицировал компонент FormLine, чтобы использовать функцию, которая передает свое состояние родительскому компоненту в качестве реквизита.

В родительском компоненте FormLineItems я написал функцию pushItem и передал ее компоненту в качестве реквизита. Теперь компонент выглядит так:

Теперь, когда вы вводите текст в поля и нажимаете «Добавить элемент», вы должны увидеть текущее состояние компонента, отображаемое над текстовыми полями.
Вы можете найти код для этой статьи наhttps://gist.github.com/vdugeri/0a9f1972b80918b624e71b9aab35cb8e