Next.js中基于当前语言环境实现Zod动态错误消息
解决Zod错误消息随语言动态更新的问题
你的问题出在Zod schema是模块加载时一次性生成的,初始化时调用i18n.t()获取的是当前语言的翻译文本,但切换语言后,schema不会重新生成,所以错误消息不会同步更新。
解决思路
把Zod schema改成函数式创建,在组件渲染时(语言切换会触发组件重渲染),使用当前语言的t函数动态生成schema,确保验证错误消息始终对应当前语言。
具体实现步骤
1. 修改Zod Schema为函数
将原来的静态schema改为接收t翻译函数的生成函数:
// my zod schema import { z } from 'zod'; export const createMailSchema = (t) => z.object({ email: z .string({ invalid_type_error: t('zod-errors.invalid_type_error'), required_error: t('zod-errors.required_error'), }) .email(t('zod-errors.email')), subject: z .string({ invalid_type_error: t('zod-errors.invalid_type_error'), required_error: t('zod-errors.required_error'), }) .min(3, t('zod-errors.min', { count: 3 })) .max(60, t('zod-errors.max', { count: 60 })), body: z .string({ invalid_type_error: t('zod-errors.invalid_type_error'), required_error: t('zod-errors.required_error'), }) .min(10, t('zod-errors.min', { count: 10 })) .max(500, t('zod-errors.max', { count: 500 })), });
2. 在表单组件中动态生成Schema
利用useTranslation获取当前语言的t函数,每次组件渲染时生成对应语言的schema,并传入react-hook-form的resolver:
import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { useTranslation } from 'next-i18next'; import { createMailSchema } from './path-to-your-schema'; export default function ContactForm() { const { t } = useTranslation(); // 语言切换时组件重渲染,这里会生成对应语言的新schema const mailSchema = createMailSchema(t); const { register, handleSubmit, formState: { errors } } = useForm({ resolver: zodResolver(mailSchema), defaultValues: { email: '', subject: '', body: '', }, }); const onSubmit = (data) => { // 处理表单提交逻辑 console.log(data); }; return ( <form onSubmit={handleSubmit(onSubmit)}> <div> <label>邮箱</label> <input {...register('email')} /> {errors.email && <p>{errors.email.message}</p>} </div> <div> <label>主题</label> <input {...register('subject')} /> {errors.subject && <p>{errors.subject.message}</p>} </div> <div> <label>内容</label> <textarea {...register('body')} /> {errors.body && <p>{errors.body.message}</p>} </div> <button type="submit">提交</button> </form> ); }
3. 完善翻译文件
确保你的多语言文件(如en.json、zh-CN.json)包含对应的占位符键值,示例:
// en.json { "zod-errors": { "invalid_type_error": "Invalid data type", "required_error": "This field is required", "email": "Please enter a valid email address", "min": "Must be at least {{count}} characters", "max": "Cannot exceed {{count}} characters" } }
// zh-CN.json { "zod-errors": { "invalid_type_error": "数据类型无效", "required_error": "此字段为必填项", "email": "请输入有效的邮箱地址", "min": "最少需要{{count}}个字符", "max": "不能超过{{count}}个字符" } }
原理说明
语言切换时,useTranslation会返回对应语言的t函数,组件触发重渲染,此时调用createMailSchema(t)生成全新的Zod schema,react-hook-form会使用这个新schema进行验证,错误消息自然会同步为当前语言的翻译。
内容的提问来源于stack exchange,提问作者Ismail_Aj
相关产品推荐
相关产品推荐

