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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 17:50:21