В связке с react-hook-form и Yup резолвер
выполняет функцию промежуточного слоя между схемой валидации и формой.
Именно на этом этапе происходит формирование структуры ошибок, их
нормализация и передача в UI. Переопределение сообщений в этом контексте
затрагивает сразу несколько уровней: сообщения внутри самой схемы Yup,
глобальные локали, трансформацию ошибок в резолвере и постобработку
результата перед возвратом в форму.
Сообщения об ошибках формируются в Yup из нескольких источников, и понимание их приоритетов критично для корректного переопределения.
Каждое правило валидации Yup содержит дефолтный текст ошибки:
Yup.string().required()
// "this field is a required field"
Эти сообщения используются, если не задано явное переопределение.
Наиболее прямой способ управления текстом ошибки — передача строки в метод валидации:
Yup.string().required('Поле обязательно для заполнения')
или с параметрами:
Yup.string().min(3, 'Минимум ${min} символа')
В этом случае Yup выполняет интерполяцию переменных
(${min}, ${max}, ${path}),
формируя итоговое сообщение.
Некоторые методы поддерживают объектный синтаксис:
Yup.string().matches(/^[a-z]+$/, {
message: 'Допустимы только латинские буквы',
excludeEmptyString: true
})
Это расширяет контроль над условиями генерации ошибки.
Yup предоставляет механизм глобальной локализации сообщений через
setLocale. Этот уровень влияет на все схемы, если не задано
локальное переопределение.
import * as Yup from 'yup'
Yup.setLocale({
mixed: {
required: 'Обязательное поле',
default: 'Некорректное значение'
},
string: {
min: 'Минимальная длина ${min} символа',
max: 'Максимальная длина ${max} символов'
},
number: {
min: 'Значение должно быть не меньше ${min}',
max: 'Значение должно быть не больше ${max}'
}
})
Приоритет сообщений строится следующим образом:
required('...'))setLocaleYupResolver не генерирует сообщения самостоятельно. Его
задача — преобразовать ошибки Yup в структуру, совместимую с
react-hook-form.
import { yupResolver } from '@hookform/resolvers/yup'
Процесс выглядит следующим образом:
ValidationErrorinner массив ошибок{
fieldName: {
type: 'validation_type',
message: 'текст ошибки'
}
}
Хотя YupResolver не предоставляет встроенного API для изменения сообщений, возможна постобработка результата.
const customResolver = async (schema, values, context, options) => {
const result = await yupResolver(schema)(values, context, options)
const transformedErrors = Object.fromEntries(
Object.entries(result.errors || {}).map(([key, error]) => {
return [
key,
{
...error,
message: `[FORM ERROR] ${error.message}`
}
]
})
)
return {
...result,
errors: transformedErrors
}
}
Такой подход используется для:
В ряде случаев требуется динамическое изменение текста в зависимости от контекста формы.
Yup поддерживает context, который передаётся из
резолвера:
Yup.string().required('${label} обязательно')
Передача контекста:
yupResolver(schema, undefined, {
context: {
label: 'Имя пользователя'
}
})
Однако прямое использование переменных контекста ограничено и часто
требует кастомных методов через test.
Yup.string().test(
'custom-check',
function (value) {
const { path, createError } = this
if (!value || value.length < 5) {
return createError({
path,
message: `Поле ${path} должно содержать минимум 5 символов`
})
}
return true
}
)
В архитектуре react-hook-form сообщения можно
модифицировать после получения результата резолвера.
setError('username', {
type: 'manual',
message: 'Пользовательское сообщение'
})
Этот механизм не связан напрямую с Yup, но часто используется для замещения сообщений, пришедших из резолвера.
При интеграции сложных схем возникает необходимость унифицировать формат сообщений.
const normalizeError = (error) => {
if (!error) return error
return {
...error,
message: error.message?.trim().replace(/\.$/, '')
}
}
Используется для:
Переопределение сообщений часто связано с интернационализацией.
Yup.setLocale({
string: {
required: 'Требуется заполнение поля'
}
})
Интеграция с i18n системами:
Yup.string().required(t('validation.required'))
или через фабрику схем:
const createSchema = (t) =>
Yup.object({
email: Yup.string().required(t('email_required'))
})
При работе с вложенными схемами ошибки могут иметь путь вида
user.email.
const flattenErrors = (errors) => {
return Object.keys(errors).reduce((acc, key) => {
acc[key.replace(/\./g, '_')] = errors[key]
return acc
}, {})
}
Это позволяет переопределять отображение сообщений в зависимости от структуры формы.
В сложных схемах с вложенными объектами и массивами действует многоуровневая система приоритетов:
testsetLocalesetErrorПри использовании yupResolver в больших формах часто
вводится слой адаптеров сообщений.
const messageAdapter = (error) => {
const dictionary = {
'this field is required': 'Обязательное поле',
'must be a valid email': 'Некорректный email'
}
return {
...error,
message: dictionary[error.message] || error.message
}
}
Такой подход позволяет отделить бизнес-логику от текстовой политики интерфейса.
При масштабировании схем важным становится предотвращение расхождений в текстах.
Используются:
yupResolverКаждый из этих уровней может перехватывать и переопределять сообщения, формируя финальный текст, отображаемый в интерфейсе.