是的,无法在 i18n 下正常工作

问题描述 投票:0回答:5

我有这段代码。我想根据用户的区域设置添加错误消息,但是是的,如果字段填写不正确,则会引发错误,同样

[缺少“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。有什么建议么?预先感谢

reactjs react-native localization internationalization yup
5个回答
19
投票

在您的架构中,替换:

.email(i18n.t('login.emailSpellError'))

.email('login.emailSpellError')

然后在你的渲染方法中:

{t(`form.errors.${form.errors.email}`)}

这假设您的翻译文件有这样的条目:

"form": { "errors": {"login": {"emailSpellError": "Your email is invalid"}}}}

这里的目标是将 t() 方法移到渲染方法中,并在那里发生所有翻译。


7
投票

是的验证方法

// 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",
}
 };  

4
投票

解决方案是创建一个返回验证模式的函数。然后在组件中调用该函数并记录结果。 这样,您就可以保证验证消息的翻译是动态计算的。

这里的另一个优势是您可以在消息的来源进行翻译。

// 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 <>...</>;
}

0
投票

我为此方法创建了一些自定义挂钩

此选项用于在更改应用程序语言时刷新架构内的错误消息

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,
});

0
投票

我在使用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
}

© www.soinside.com 2019 - 2024. All rights reserved.