Связь нескольких форм

Ant Design предоставляет мощный инструмент для работы с формами через компонент Form, который позволяет управлять состоянием, валидацией и взаимодействием с пользователем. Когда приложение содержит несколько форм, часто возникает необходимость синхронизировать их данные, управлять зависимостями и централизованно обрабатывать события.

Создание нескольких форм

Для начала необходимо импортировать компоненты:

import React from 'react';
import { Form, Input, Button } from 'antd';

Каждая форма создается с помощью Form.useForm(). Это возвращает объект формы, который обеспечивает управление состоянием и методами для программной работы:

const [formA] = Form.useForm();
const [formB] = Form.useForm();

Каждую форму можно рендерить независимо, но управлять их значениями централизованно.

Синхронизация данных между формами

Частая задача — автоматическое обновление одной формы при изменении другой. Для этого используется метод form.setFieldsValue.

const onValuesChan geA = (changedValues, allValues) => {
  formB.setFieldsValue({
    username: allValues.username,
  });
};

В этом примере любое изменение поля username в formA мгновенно обновляет соответствующее поле в formB.

Обработка нескольких форм при отправке

Иногда требуется отправить данные сразу из нескольких форм. Для этого используют Promise.all, чтобы дождаться валидации всех форм:

const handleSubmit = async () => {
  try {
    const values = await Promise.all([formA.validateFields(), formB.validateFields()]);
    console.log('Данные всех форм:', values);
  } catch (error) {
    console.error('Ошибка валидации', error);
  }
};

Метод validateFields возвращает промис, который выполняется только при успешной валидации. Это гарантирует целостность данных.

Использование зависимостей между полями

Ant Design позволяет устанавливать зависимости между полями внутри и между формами через Form.Item с атрибутом dependencies.

<Form form={formA}>
  <Form.Item name="age" label="Возраст">
    <Input type="number" />
  </Form.Item>

  <Form.Item
    name="canDrink"
    label="Можно пить алкоголь"
    dependencies={['age']}
    shouldUpdate={(prevValues, currentValues) => prevValues.age !== currentValues.age}
  >
    {({ getFieldValue }) => (
      <Input value={getFieldValue('age') >= 18 ? 'Да' : 'Нет'} readOnly />
    )}
  </Form.Item>
</Form>

Такое решение позволяет автоматически обновлять поля на основе других значений без необходимости вручную подписываться на события.

Централизованное управление формами

Для больших приложений удобно хранить состояния всех форм в едином объекте или использовать контекст React. Это позволяет вызывать методы setFieldsValue, validateFields и resetFields из любого компонента.

const formsContext = {
  formA,
  formB,
};

const resetAllForms = () => {
  Object.values(formsContext).forEach(form => form.resetFields());
};

Таким образом, можно быстро сбросить все формы или обновить их значения централизованно.

Кастомная валидация между формами

Валидация, зависящая от нескольких форм, выполняется через validator в rules:

<Form.Item
  name="confirmPassword"
  label="Подтверждение пароля"
  dependencies={['password']}
  rules={[
    { required: true, message: 'Введите подтверждение' },
    ({ getFieldValue }) => ({
      validator(_, value) {
        if (!value || getFieldValue('password') === value) {
          return Promise.resolve();
        }
        return Promise.reject(new Error('Пароли не совпадают'));
      },
    }),
  ]}
>
  <Input.Password />
</Form.Item>

Этот подход позволяет проверять данные в зависимости от состояния других форм и предотвращать неконсистентные значения.

Оптимизация производительности

При множестве форм важно избегать лишних перерисовок. Использование shouldUpdate и Form.Item с функцией-рендерером позволяет обновлять только необходимые элементы.

<Form.Item shouldUpdate={(prev, curr) => prev.value !== curr.value}>
  {({ getFieldValue }) => <span>{getFieldValue('value')}</span>}
</Form.Item>

Такой подход минимизирует нагрузку на рендеринг при изменении данных в других формах.

Резюме ключевых методов для нескольких форм

  • Form.useForm() — создание и управление формой.
  • form.setFieldsValue() — синхронизация значений между формами.
  • form.validateFields() — проверка и получение данных формы.
  • form.resetFields() — сброс значений формы.
  • dependencies и shouldUpdate — динамическое обновление полей.
  • Кастомные валидаторы через rules — проверка на основе нескольких полей и форм.

Использование этих инструментов обеспечивает гибкую, масштабируемую и управляемую архитектуру форм в приложениях на JavaScript с библиотекой Ant Design.