Флаги setValue в React Hook Form: shouldValidate и shouldDirty

    При работе с формами в React Hook Form, особенно с зависимыми мульти-селектами (страны, регионы, города), часто возникает необходимость программно обновлять значения полей с помощью метода setValue. Этот метод принимает два опциональных флага: shouldValidate и shouldDirty. Правильное их использование критически важно для корректной валидации и отслеживания состояния формы.

    Что такое shouldValidate?

    Флаг shouldValidate определяет, нужно ли запускать повторную валидацию поля, значение которого вы изменяете через setValue. По умолчанию он равен false. Если вы хотите, чтобы после изменения поля сразу проверялись правила валидации (например, обязательность поля, минимальная длина и т.д.), передайте true. В вашем сценарии с селектами стран и регионов, где поля не должны быть пустыми, использование shouldValidate: true поможет сразу показывать ошибки пользователю при удалении зависимых элементов.

    Что такое shouldDirty?

    Флаг shouldDirty указывает, должно ли поле считаться изменённым пользователем (dirty). По умолчанию false. Если вы программно обновляете поле, но хотите, чтобы оно помечалось как dirty (например, для корректной работы кнопки сброса или отображения индикатора изменений), установите true. В вашем случае, когда удаление страны приводит к очистке регионов и городов, логично сделать эти поля dirty, чтобы пользователь видел, что форма изменилась.

    Практический пример с зависимыми селектами

    Допустим, у вас есть форма с тремя мульти-селектами: страны, регионы, города. При удалении страны нужно очистить связанные регионы и города. Вот как это реализовать с правильными флагами:

    const handleCountryRemove = (removedCountry) => {
      const filteredRegions = regions.filter(r => r.countryId !== removedCountry.id);
      const filteredCities = cities.filter(c => c.countryId !== removedCountry.id);
      
      setValue('regions', filteredRegions, { 
        shouldValidate: true, 
        shouldDirty: true 
      });
      setValue('cities', filteredCities, { 
        shouldValidate: false, 
        shouldDirty: true 
      });
    };

    Обратите внимание: для поля регионов мы включаем валидацию (так как оно обязательное), а для городов - нет (так как города могут быть пустыми). Оба поля помечаем как dirty.

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

    shouldValidate: true

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

    shouldValidate: false

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

    shouldDirty: true

    • Когда нужно, чтобы форма знала о внесённых изменениях (для активации кнопки «Сохранить»)
    • При очистке зависимых полей после удаления родительского элемента
    • Когда вы используете isDirty для блокировки кнопки отправки

    shouldDirty: false

    • Когда вы программно устанавливаете начальные значения при загрузке данных
    • Когда изменение не должно считаться действием пользователя (например, синхронизация с сервером)

    Рекомендации для вашего сценария

    Для формы с зависимыми мульти-селектами используйте следующую стратегию:

    • При удалении страны: setValue('regions', ...) с shouldValidate: true, shouldDirty: true. Для городов: setValue('cities', ...) с shouldValidate: false, shouldDirty: true.
    • При удалении региона: setValue('cities', ...) с shouldValidate: false, shouldDirty: true.
    • При добавлении новых элементов (например, выборе страны) не используйте setValue, если не нужно очищать зависимые поля.

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

    Часто задаваемые вопросы