2.1 KiB
2.1 KiB
title, impact, impactDescription, tags
| title | impact | impactDescription | tags |
|---|---|---|---|
| Use delayError to Debounce Rapid Error Display | MEDIUM | reduces UI flicker during fast typing validation | valid, delayError, debounce, user-experience |
Use delayError to Debounce Rapid Error Display
When using onChange mode, errors appear and disappear rapidly as users type. Use delayError to add a small delay, preventing UI flicker while still providing timely feedback.
Incorrect (errors flash rapidly during typing):
function SearchForm() {
const { register, formState: { errors } } = useForm({
mode: 'onChange',
})
return (
<form>
<input {...register('query', { minLength: 3 })} />
{errors.query && <span>Min 3 characters</span>} {/* Flashes on/off rapidly */}
</form>
)
}
Correct (error display debounced):
function SearchForm() {
const { register, formState: { errors } } = useForm({
mode: 'onChange',
delayError: 300, // 300ms delay before showing errors
})
return (
<form>
<input {...register('query', { minLength: 3 })} />
{errors.query && <span>Min 3 characters</span>} {/* Appears after 300ms delay */}
</form>
)
}
When to use:
- Real-time validation with
onChangemode - Fields with character count requirements
- Search inputs with minimum length
Opting a single setValue into the delay (7.82+): setValue accepts delayError, but it is a boolean — it opts that call into the debounce, and the duration still comes from useForm({ delayError }). Passing a number is a type error, even though the 7.82.0 release notes show delayError: 500:
const { setValue } = useForm({ mode: 'onChange', delayError: 300 })
setValue('query', suggestion, { shouldValidate: true, delayError: true }) // debounced by 300ms
Without a form-level delayError, { delayError: true } on setValue has nothing to debounce with and the error appears immediately.
Reference: useForm - delayError · useForm - setValue