You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何结合i18n/intl国际化转换Formik与Yup的报错信息

Formik+Yup 表单校验错误国际化实现方案

你现有的多语言JSON配置方案可以直接复用,不需要额外引入复杂依赖,按以下步骤配置即可:

  • 先在各语言JSON配置文件中补充校验类词条
    按你现有的多语言文件结构,把所有表单校验用到的提示文案提前写到对应语言包中,支持插值占位符匹配动态参数,示例:

    // 中文语言包 zh-CN.json
    {
      "validation": {
        "required": "此项为必填项",
        "invalidEmail": "请输入格式正确的邮箱地址",
        "minLength": "输入内容最少需要{min}个字符",
        "maxLength": "输入内容最多不能超过{max}个字符",
        "confirmPasswordNotMatch": "两次输入的密码不一致"
      }
    }
    
    // 英文语言包 en-US.json
    {
      "validation": {
        "required": "This field is required",
        "invalidEmail": "Please enter a valid email address",
        "minLength": "Minimum {min} characters required",
        "maxLength": "Maximum {max} characters allowed",
        "confirmPasswordNotMatch": "Passwords do not match"
      }
    }
    
  • Yup校验规则直接对接i18n实例取多语言文案
    不要在Yup校验Schema中硬编码任何提示文案,直接调用i18n的翻译方法获取对应语言词条,带动态参数的规则直接传插值对象即可。

    注意:如果在React组件外部定义校验Schema,直接引入项目中初始化完成的i18n实例调用t方法即可,不要在组件外使用React版i18n的hook,会触发报错;组件内定义Schema可以直接用useTranslation hook拿到翻译方法。
    示例代码:

    import * as Yup from 'yup'
    // 组件外引入初始化好的i18n实例
    import i18n from '@/i18n'
    
    // 组件外定义的通用校验规则
    export const baseUserSchema = Yup.object({
      email: Yup.string()
        .required(i18n.t('validation.required'))
        .email(i18n.t('validation.invalidEmail')),
      password: Yup.string()
        .required(i18n.t('validation.required'))
        .min(8, i18n.t('validation.minLength', { min: 8 }))
    })
    
  • 处理语言切换时校验文案不更新的问题
    很多人接入后会遇到切语言后表单报错还是旧语言的问题,原因是校验Schema只在组件首次渲染时生成了一次,没有跟着语言变化更新。只需要把Schema的生成逻辑用useMemo包裹,把当前语言作为依赖项即可,Formik会自动使用最新的校验规则:

    import { useFormik } from 'formik'
    import { useTranslation } from 'react-i18next'
    import * as Yup from 'yup'
    
    const AccountForm = () => {
      const { t, i18n } = useTranslation()
      // 语言变化时自动重新生成校验Schema
      const validationSchema = useMemo(() => {
        return Yup.object({
          confirmPassword: Yup.string()
            .required(t('validation.required'))
            .oneOf([Yup.ref('password'), null], t('validation.confirmPasswordNotMatch'))
        })
      }, [i18n.language, t])
    
      const formik = useFormik({
        initialValues: { password: '', confirmPassword: '' },
        validationSchema,
        onSubmit: (values) => {
          // 表单提交逻辑
        }
      })
    
      // 渲染部分直接取formik.errors即可,内容已经是当前语言的提示
      return (
        <form onSubmit={formik.handleSubmit}>
          <div>
            <input
              name="confirmPassword"
              type="password"
              value={formik.values.confirmPassword}
              onChange={formik.handleChange}
              onBlur={formik.handleBlur}
            />
            {formik.touched.confirmPassword && formik.errors.confirmPassword && (
              <div className="error-tip">{formik.errors.confirmPassword}</div>
            )}
          </div>
          <button type="submit">提交</button>
        </form>
      )
    }
    
  • 可选优化:全局配置Yup默认提示,减少重复代码
    如果项目里表单多、校验规则重复度高,可以用Yup的setLocale方法全局配置默认校验提示,写规则的时候不需要重复传文案参数。只需要在i18n初始化完成后配置一次,同时监听语言切换事件更新全局配置即可:

    // i18n初始化文件中
    import * as Yup from 'yup'
    import i18n from './index'
    
    const updateYupDefaultMessage = () => {
      Yup.setLocale({
        mixed: {
          required: i18n.t('validation.required')
        },
        string: {
          email: i18n.t('validation.invalidEmail'),
          min: ({ min }) => i18n.t('validation.minLength', { min }),
          max: ({ max }) => i18n.t('validation.maxLength', { max })
        }
      })
    }
    // 初始化时执行一次
    updateYupDefaultMessage()
    // 语言切换时自动更新默认提示
    i18n.on('languageChanged', updateYupDefaultMessage)
    

    配置完成后写校验规则不需要再传message参数,默认就会使用对应语言的全局配置:

    // 不需要每个规则都写t方法传文案
    const simpleSchema = Yup.object({
      email: Yup.string().required().email(),
      password: Yup.string().required().min(8)
    })
    

内容的提问来源于stack exchange,提问作者Puneet Phull

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 17:09:14