Гибко настраиваемая форма с динамическим набором полей в React

Храните поля как записи с ID и value: устойчивый ID сохраняет идентичность после удаления. Удаление последней строки запрещайте отдельно.

Короткий ответ

Что ответить на собеседовании

Храните поля как записи с ID и value: устойчивый ID сохраняет идентичность после удаления. Удаление последней строки запрещайте отдельно.

Подробный разбор

Ответ с пояснениями

Условие

Создайте компонент DynamicForm, позволяющий пользователю в реальном времени добавлять и удалять текстовые поля ввода.

Требования:

  1. Реализуйте компонент DynamicForm, который поддерживает динамическое добавление и удаление полей ввода.
  2. При загрузке формы должна быть уже присутствующая одна текстовая строка.
  3. При нажатии на кнопку «Добавить поле» появляется новое текстовое поле.
  4. Рядом с каждым полем размещается кнопка «Удалить», позволяющая удалить конкретное поле, если в форме больше одного.
  5. Любое изменение любого из полей должно обновлять массив значений, хранящийся в useState, и выводить его в console.log.
  6. Добавьте кнопку «Отправить», при клике по которой в консоль выводятся все текущие введённые данные.
  7. Для отображения списка полей используйте useState и метод map().
import "./styles.css";

// Требования:
// 1. Создай компонент DynamicForm, который позволяет пользователю динамически добавлять и удалять поля ввода.
// 2. В начале форма должна содержать одно текстовое поле.
// 3. Пользователь может нажать кнопку "Добавить поле", чтобы добавить новое текстовое поле.
// 4. Возле каждого поля должна быть кнопка "Удалить", позволяющая удалить конкретное поле (если оно не единственное).
// 5. При изменении любого поля, обновлённый список значений должен храниться в useState и отображаться в console.log.
// 6. Добавь кнопку "Отправить", которая выведет в консоль все введённые данные.
// 7. Используй useState и map() для рендеринга динамического списка полей.

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

Ответ

Храните поля как записи с ID и value: устойчивый ID сохраняет идентичность после удаления. Удаление последней строки запрещайте отдельно.

function DynamicForm() {
  const [fields, setFields] = React.useState([{ id: 0, value: '' }]);
  const nextId = React.useRef(1);
  React.useEffect(() => { console.log(fields.map(field => field.value)); }, [fields]);
  function add() {
    const field = { id: nextId.current++, value: '' };
    setFields(current => [...current, field]);
  }
  return <form onSubmit={event => { event.preventDefault(); console.log(fields.map(field => field.value)); }}>
    {fields.map((field, index) => <div key={field.id}>
      <label>Поле {index + 1} <input value={field.value} onChange={event => {
        const value = event.target.value;
        setFields(current => current.map(item => item.id === field.id ? { ...item, value } : item));
      }} /></label>
      <button type='button' disabled={fields.length === 1} onClick={() => setFields(current => current.length > 1 ? current.filter(item => item.id !== field.id) : current)}>Удалить</button>
    </div>)}
    <button type='button' onClick={add}>Добавить поле</button>
    <button>Отправить</button>
  </form>;
}

В App отобразите <DynamicForm />. Логирование вынесено из updater-функций, которые должны быть чистыми. В production чувствительные данные формы журналировать не следует.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее