我有这段代码。我想根据用户的区域设置添加错误消息,但是是的,如果字段填写不正确,则会引发错误,同样
[缺少“en.login.emailRequiredError”翻译] [缺少“en.login.passRequiredError”翻译]
const schema = yup.object().shape({
email: yup
.string()
.email(i18n.t('login.emailSpellError'))
.required(i18n.t('login.emailRequiredError')),
password: yup
.string()
.matches(/^((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,15})$/i, i18n.t('login.passSpellError'))
.required(i18n.t('login.passRequiredError')),
});
当我将它放入渲染方法中进行检查时,i18n.t('login.passRequiredError') 工作正常,但它不适用于 yup。有什么建议么?预先感谢
在您的架构中,替换:
.email(i18n.t('login.emailSpellError'))
与
.email('login.emailSpellError')
然后在你的渲染方法中:
{t(`form.errors.${form.errors.email}`)}
这假设您的翻译文件有这样的条目:
"form": { "errors": {"login": {"emailSpellError": "Your email is invalid"}}}}
这里的目标是将 t() 方法移到渲染方法中,并在那里发生所有翻译。
是的验证方法,
// You define the key mentioned in the translation file, in my example 'Invalid email' and 'Required'
let ForgotPasswordSchema = yup.object().shape({
email: yup.string().email('Invalid email').required('Required'),
});
在渲染方法中,
// As per your definition
isInvalid={(!!errors.email) && this.context.t(!!errors.email)}
invalidText={(errors.email) && this.context.t(errors.email)}
翻译文件
export const translations = {
"cy": {
"Required":"Gofynnol",
"Invalid email":"Nid yw'r cyfeiriad ebost yn ddilys",
}
};
解决方案是创建一个返回验证模式的函数。然后在组件中调用该函数并记录结果。 这样,您就可以保证验证消息的翻译是动态计算的。
这里的另一个优势是您可以在消息的来源进行翻译。
// Translation file
{
"validation.invalid-email": "Email is invalid",
"validation.field-required": "Field is required"
}
// Validation schema
const forgotPasswordSchema = () => {
return yup.object().shape({
email: yup
.string()
.email(i18n.t('validation.invalid-email'))
.required(i18n.t('validation.field-required')),
});
};
// Your component
const FormComponent = () => {
const schema = useMemo(() => forgotPasswordSchema(), [i18n.language]); // NB: `[i18n.language]` is optional and `[]` will suffice depending on how you're handling language change
return <>...</>;
}
我为此方法创建了一些自定义挂钩
此选项用于在更改应用程序语言时刷新架构内的错误消息
import { yupResolver } from '@hookform/resolvers/yup';
import { useRouter } from 'next/router';
import { useMemo } from 'react';
const useSchema = (getSchema) => {
const { locale } = useRouter();
const resolver = useMemo(getSchema, [locale]);
return yupResolver(resolver);
};
export default useSchema;
这个在应用程序组件本地化错误消息中设置全局
import { useTranslation } from 'react-i18next';
import { setLocale } from 'yup';
export const useLocalisedYupSchema = () => {
const { t } = useTranslation('common');
setLocale({
mixed: {
required: t('validation.required')
},
string: {
min: ({ min }) => t('validation.min', { min }),
max: ({ max }) => t('validation.max', { max })
},
});
};
还可以使用 React Hook Form 来使用组件内部的模式
import { getChangePasswordSchema } from 'static/schemas/changePassword';
import useSchema from 'utils/hooks/useSchema';
import { useForm } from 'react-hook-form';
const AccountContentSecurity = () => {
...
const resolver = useSchema(getChangePasswordSchema);
const { reset, control, handleSubmit } = useForm({
defaultValues: {
'current_password': '',
'new_password': '',
'password_confirmation': '',
},
resolver,
});
...
和架构
import { passwordSchema } from 'static/schemas';
import { object } from 'yup';
export const getChangePasswordSchema = () => object({
'current_password': passwordSchema,
'new_password': passwordSchema,
'password_confirmation': passwordSchema,
});
我在使用react-hook-form时遇到了这个问题,我通过在表单处理hook中添加useEffect解决了这个问题
export type LoginFormType = {
captcha: string
email: string
password: string
}
export const getLoginFormSchema = (): ObjectSchema<LoginFormType> =>
yup.object({
captcha: yup.string().required(i18n.t('Enter code from image')).trim(),
email: yup
.string()
.required(i18n.t('Enter your email'))
.matches(emailRegex, i18n.t('Enter a valid email address'))
.trim(),
password: yup.string().required(i18n.t('Enter the password')).trim(),
})
export const defaultValues: LoginFormType = {
captcha: '',
email: '',
password: '',
}
export const useLoginForm = (defValue?: Partial<LoginFormType>): UseFormReturn<LoginFormType> => {
const schema = useMemo(() => getLoginFormSchema(), [i18n.language])
const form = useForm({
defaultValues: {
...defaultValues,
...defValue,
},
mode: 'onSubmit',
resolver: yupResolver(schema),
})
useEffect(() => {
form.trigger().then()
}, [i18n.language])
return form
}