React Hook Form: reset vs setValue — в чём разница

Обновлено:

На днях обнаружил, что formHook.reset и formHook.setValue работают по-разному, и даже если в formHook.reset передать только одно поле, это может повлиять на всю форму. Разберёмся, в чём разница и когда что использовать.

1. formHook.reset

Как это работает

  • reset полностью сбрасывает состояние формы, заменяя его новыми значениями.
  • Если передать только одно поле, все остальные поля формы сбросятся в undefined или в значения по умолчанию.

Пример

onSubmit={(fv) => formHook.reset({ [name]: fv })}

Что происходит

  • Форма полностью сбрасывается.
  • Поле name (например, suspensiveConditions) получает новое значение fv.
  • Все остальные поля теряют свои текущие значения.

Когда использовать

  • Если нужно полностью сбросить форму и обновить только одно поле.
  • Подходит для простых случаев, когда форма содержит мало полей или их сброс не вызывает проблем.

2. formHook.setValue

Как это работает

  • setValue обновляет только указанные поля формы, не затрагивая остальные.
  • Можно обновлять вложенные поля (например, suspensiveConditions.startDate).

Пример

onSubmit={(fv) => {
  objectForEach(fv, (value, key) => {
    formHook.setValue(`${name}.${key}`, value);
  });
}}

Что происходит

  • Каждое поле внутри fv обновляется отдельно.
  • Только указанные поля изменяются, остальные поля формы остаются без изменений.

Когда использовать

  • Если нужно обновить только определённые поля, не затрагивая остальные.
  • Подходит для сложных форм, где важно сохранить состояние других полей.

Разница в поведении

КритерийformHook.resetformHook.setValue с итерацией
Сброс формыПолностью сбрасывает формуНе сбрасывает форму
Обновление полейОбновляет только поле nameОбновляет только указанные поля
Влияние на другие поляВсе остальные поля сбрасываютсяОстальные поля остаются без изменений
ГибкостьНизкая (обновляет только одно поле)Высокая (можно обновлять вложенные поля)
ПростотаПростой и короткий кодБолее сложный код

Пример

Исходные данные

Форма содержит поля:

  • suspensiveConditions.startDate
  • suspensiveConditions.endDate
  • otherField

С formHook.reset

onSubmit={(fv) => formHook.reset({ suspensiveConditions: fv })}

После выполнения:

  • suspensiveConditions.startDate и suspensiveConditions.endDate обновляются.
  • otherField сбрасывается в undefined.

С formHook.setValue

onSubmit={(fv) => {
  objectForEach(fv, (value, key) => {
    formHook.setValue(`suspensiveConditions.${key}`, value);
  });
}}

После выполнения:

  • suspensiveConditions.startDate и suspensiveConditions.endDate обновляются.
  • otherField остаётся без изменений.

Сохранение состояния перед reset

Если всё же нужно использовать reset, но сохранить текущие значения других полей, можно объединить их с помощью getValues:

onSubmit={(fv) => {
  const currentValues = formHook.getValues();
  formHook.reset({ ...currentValues, [name]: fv });
}}

Так вы обновляете нужное поле, не теряя остальные.

Итог

  • formHook.reset полностью сбрасывает форму, обновляя только указанное поле.
  • formHook.setValue обновляет только указанные поля, не затрагивая остальные.

Выбор подхода зависит от ваших требований: если нужно сохранить состояние других полей, используйте setValue; если сброс формы допустим, используйте reset.

А вы сталкивались с подобными ситуациями?