使用Mantine use-form结合real-i18next useTranslation做表单验证遇翻译问题求助
解决react-i18next useTranslation 配合 Mantine use-form 翻译失效问题
这个问题通常出现在Mantine use-form 初始化时,翻译函数t还未完成加载,导致验证规则里的错误提示直接使用了未翻译的key,只有刷新后i18n完成初始化,t函数才能正常工作。下面是具体的解决思路和代码示例:
核心原因
Mantine use-form 的验证规则会在组件挂载初期就被创建,如果此时react-i18next还没完成语言包加载,或者t函数没有被正确纳入依赖跟踪,就会出现初始状态下错误提示未翻译的情况。
解决方案
1. 动态在验证函数中调用t
不要在验证规则的静态值中直接调用t,而是在验证函数内部动态调用,确保每次验证时都使用最新的翻译状态:
import { useForm } from '@mantine/form'; import { useTranslation } from 'react-i18next'; function MyForm() { const { t } = useTranslation(); const form = useForm({ initialValues: { email: '' }, validate: { email: (value) => { if (!value) return t('form.errors.required'); if (!/^\S+@\S+$/.test(value)) return t('form.errors.invalidEmail'); return null; }, }, }); // ...表单渲染逻辑 }
2. 依赖t更新验证规则
如果需要提前定义验证规则结构,可以用useMemo将验证规则与t绑定,确保t更新时验证规则也重新生成:
import { useMemo } from 'react'; import { useForm } from '@mantine/form'; import { useTranslation } from 'react-i18next'; function MyForm() { const { t } = useTranslation(); const validationRules = useMemo(() => ({ email: (value) => { if (!value) return t('form.errors.required'); if (!/^\S+@\S+$/.test(value)) return t('form.errors.invalidEmail'); return null; }, password: (value) => { if (value.length < 6) return t('form.errors.passwordLength'); return null; }, }), [t]); const form = useForm({ initialValues: { email: '', password: '' }, validate: validationRules, }); // ...表单渲染逻辑 }
3. 等待i18n加载完成后初始化表单
如果你的语言包是异步加载的,可以利用react-i18next的ready状态,等待翻译加载完成后再渲染表单:
import { useForm } from '@mantine/form'; import { useTranslation } from 'react-i18next'; function MyForm() { const { t, ready } = useTranslation(); if (!ready) { return <div>Loading translations...</div>; } const form = useForm({ initialValues: { email: '' }, validate: { email: (value) => { if (!value) return t('form.errors.required'); return null; }, }, }); // ...表单渲染逻辑 }
4. 确保i18n全局初始化完成
在应用入口文件(比如index.tsx)中,先完成i18n的初始化,再渲染根组件,避免组件挂载时翻译还未准备好:
import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import i18n from './i18n'; // 你的i18n配置文件 import { I18nextProvider } from 'react-i18next'; // 确保i18n初始化完成后再渲染 i18n.init().then(() => { const root = ReactDOM.createRoot( document.getElementById('root') as HTMLElement ); root.render( <I18nextProvider i18n={i18n}> <App /> </I18nextProvider> ); });
内容的提问来源于stack exchange,提问作者Nandatto
相关产品推荐
相关产品推荐

