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

React Formik:如何停止对禁用/隐藏/未渲染控件的Yup校验

解决Yup对禁用/不可见/未渲染控件的校验问题

方法1:利用Yup的when条件校验(适配禁用/不可见控件)

通过将控件的禁用/可见状态传入Yup上下文,动态决定是否校验该字段。

修改校验规则:

const validationSchema = Yup.object({
  mandant: Yup.number()
    // $isMandantDisabled 是传入上下文的状态变量
    .when('$isMandantDisabled', {
      is: true, // 当控件禁用时
      then: schema => schema.notRequired(), // 取消必填校验
      otherwise: schema => schema.min(1, 'Select Mandant').required() // 正常校验
    })
});

结合表单库(以Formik为例)传入状态:

<Formik
  initialValues={{ mandant: '' }}
  validationSchema={validationSchema}
  // 将控件的禁用状态传入Yup上下文
  context={{ isMandantDisabled: true }}
  onSubmit={handleSubmit}
>
  {() => (
    <MySelectInput 
      disabled={true} 
      placeholder={mandantOptions[0].text} 
      name="mandant" 
      options={mandantOptions} 
      clearable={false} 
    />
  )}
</Formik>

如果是不可见控件,只需将上下文变量换成$isMandantVisible,调整判断逻辑即可。

方法2:动态生成校验规则(适配未渲染控件)

如果控件是根据条件动态渲染的,可同步动态生成对应的校验字段,完全排除未渲染字段的校验。

// shouldRenderMandant 是控制控件是否渲染的条件变量
const validationFields = {};
if (shouldRenderMandant) {
  validationFields.mandant = Yup.number().min(1, 'Select Mandant').required();
}

const validationSchema = Yup.object(validationFields);

方法3:提交前过滤字段(复杂场景适配)

如果上述方法不适用,可在提交前手动过滤掉无需校验的字段,再执行校验逻辑:

const handleSubmit = async (values, { setErrors, setSubmitting }) => {
  // disabledFields 是记录所有禁用/未渲染字段名的数组
  const filteredValues = { ...values };
  disabledFields.forEach(field => delete filteredValues[field]);

  try {
    // 仅校验过滤后的字段
    await validationSchema.validate(filteredValues, { abortEarly: false });
    // 执行实际提交逻辑
  } catch (err) {
    // 整理错误信息并设置
    const errors = err.inner.reduce((acc, curr) => {
      acc[curr.path] = curr.message;
      return acc;
    }, {});
    setErrors(errors);
  } finally {
    setSubmitting(false);
  }
};

内容的提问来源于stack exchange,提问作者Andreas Frank

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 16:40:01