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

使用Yup与React Hook Form时如何配置多套表单校验schema?

Yup 多表单差异化校验配置方案

方案1:拆分独立Schema(最推荐)

将公共字段的校验规则抽离复用,分别为登录、注册表单定义独立的schema,从根源避免无关字段的校验逻辑互相干扰。
代码示例:

// 抽离公共校验规则实现复用
const commonEmailRule = yup.string().email("邮箱格式不正确").required("邮箱不能为空");
const commonPasswordRule = yup.string().min(4, "密码最少4位").max(20, "密码最多20位").required("密码不能为空");

// 登录表单专属校验Schema
const loginSchema = yup.object().shape({
  email: commonEmailRule,
  password: commonPasswordRule
});

// 注册表单专属校验Schema
const registerSchema = yup.object().shape({
  email: commonEmailRule,
  password: commonPasswordRule,
  userName: yup.string().required("用户名不能为空").min(2, "用户名最少2位"),
  repeatPassword: yup.string()
    .required("请确认密码")
    .oneOf([yup.ref("password")], "两次输入的密码不一致")
});

使用时分别给两个表单的useForm注入对应schema即可:

// 登录表单配置
const { control, handleSubmit, formState: { errors } } = useForm<IFormInputs>({
  resolver: yupResolver(loginSchema)
});

// 注册表单配置
const { control, handleSubmit, formState: { errors } } = useForm<IRegisterFormInputs>({
  resolver: yupResolver(registerSchema)
});

方案2:单Schema条件校验(适合字段差异极小的场景)

如果需要复用同一个schema,可以通过Yup的when方法,根据表单标识字段动态切换校验规则。
首先需要在表单中新增一个标识字段(可设为隐藏不展示),用来区分当前是登录还是注册场景:

const schema = yup.object().shape({
  // 表单类型标识,可选值 login/register
  formType: yup.string().oneOf(["login", "register"]).required(),
  email: commonEmailRule,
  password: commonPasswordRule,
  // 仅注册场景校验用户名字段
  userName: yup.string().when("formType", {
    is: "register",
    then: (schema) => schema.required("用户名不能为空").min(2),
    otherwise: (schema) => schema.notRequired()
  }),
  // 仅注册场景校验确认密码字段
  repeatPassword: yup.string().when("formType", {
    is: "register",
    then: (schema) => schema.required("请确认密码").oneOf([yup.ref("password")], "两次密码输入不一致"),
    otherwise: (schema) => schema.notRequired()
  })
});

使用时需要在对应表单的useForm配置中传入对应的formType默认值:

// 登录表单配置
const { control, handleSubmit, formState: { errors } } = useForm<IFormInputs>({
  resolver: yupResolver(schema),
  defaultValues: {
    formType: "login"
  }
});

// 注册表单配置
const { control, handleSubmit, formState: { errors } } = useForm<IFormInputs>({
  resolver: yupResolver(schema),
  defaultValues: {
    formType: "register"
  }
});

原问题原因说明

Yup默认会对schema中定义的所有字段执行校验,如果登录表单没有提交userName、repeatPassword字段,schema会将其识别为undefined触发校验报错,因此优先推荐拆分独立schema的方案,逻辑更清晰、维护成本更低。

内容的提问来源于stack exchange,提问作者Peter Boomsma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:45:04