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

Yup校验时日期选择器与下拉框红色样式不显示问题

问题描述
  • 使用Yup配合React Hook Form做表单校验时,日期选择器的标签、底部边框,以及下拉框的标签未显示红色错误样式。
  • 问题表现:
    • 校验不通过时,日期选择器的标签和底部边框未变红
    • 下拉框校验失败时,标签未显示红色
  • 期望效果:校验不通过时,上述元素均显示红色错误样式。

相关代码

下拉框组件代码

<FormInputDropdown
              name='typeId'
              type='text'
              control={control}
              options={TypeData}
              label='Type'
              helperText={errors?.typeId?.message}
              errors={!!errors.typeId}
              register={register('typeId', {
                onChange: (e) => dispatch(setTypeId(e.target.value)),
              })}
            />

日期选择器组件代码

<FormInputDate
              name='acquired'
              control={control}
              label='Date Acquired'
              maxDate={defaultValue.verified}
              helperText={errors?.acquired?.message}
              errors={!!errors.acquired}
              register={register('acquired', {
                onChange: (e) => dispatch(setAcquired(e.target.value)),
              })}
            />

Yup校验规则代码

const input_schema = yup.object().shape({
  assetTag: yup
    .string()
    .max(128, requiredLimit)
    .required(requiredField)
    .nullable(),
  typeId: yup.string().required(requiredField).nullable(),
  manu: yup.string().max(128, requiredLimit).required(requiredField),
  model: yup.string().max(128, requiredLimit).required(requiredField),
  locationId: yup.string().required(requiredField),
  fundingId: yup.string().required(requiredField),
  buildingId: yup.string().required(requiredField),
  serial: yup.string().max(128, requiredLimit).required(requiredField),
  acquired: yup.date().required().typeError(requiredField),
  verified: yup.date().required().typeError(requiredField),
});

useForm配置代码

const useFunction = useForm({
    mode: 'onChange',
    defaultValues: defaultValue,
    resolver: yupResolver(input_schema),
  });

解决方案

问题核心是自定义组件未根据errors状态正确渲染红色样式,同时组件与React Hook Form的状态同步存在问题,可按以下步骤修复:

  1. 让自定义组件响应errors状态
    检查FormInputDropdown和FormInputDate内部逻辑,确保当传入的errors为true时,给对应元素添加红色样式:

    • 标签:给<label>元素添加红色文本类(如text-red-500)
    • 日期选择器边框:给输入框元素添加红色边框类(如border-red-500)

    示例(以FormInputDate为例):

    // FormInputDate组件内部实现
    const FormInputDate = ({ label, errors, helperText, ...rest }) => {
      return (
        <div className="form-field">
          <label className={`label ${errors ? 'text-red-500' : ''}`}>{label}</label>
          <input 
            type="date" 
            className={`input-field ${errors ? 'border-red-500' : ''}`} 
            {...rest} 
          />
          {errors && <span className="error-text text-red-500">{helperText}</span>}
        </div>
      )
    }
    
  2. 改用Controller同步表单状态
    当前同时传入control和register容易导致状态不一致,推荐用React Hook Form的Controller组件包裹自定义组件,确保错误状态同步:

    调整下拉框代码:

    <Controller
      name="typeId"
      control={control}
      render={({ field }) => (
        <FormInputDropdown
          {...field}
          options={TypeData}
          label="Type"
          helperText={errors?.typeId?.message}
          errors={!!errors.typeId}
          onChange={(e) => {
            field.onChange(e);
            dispatch(setTypeId(e.target.value));
          }}
        />
      )}
    />
    

    日期选择器同理:

    <Controller
      name="acquired"
      control={control}
      render={({ field }) => (
        <FormInputDate
          {...field}
          label="Date Acquired"
          maxDate={defaultValue.verified}
          helperText={errors?.acquired?.message}
          errors={!!errors.acquired}
          onChange={(e) => {
            field.onChange(e);
            dispatch(setAcquired(e.target.value));
          }}
        />
      )}
    />
    
  3. 确保样式优先级
    检查自定义组件的默认样式,避免错误样式被更高优先级的默认样式覆盖。可通过增加CSS选择器特异性,或在必要时使用!important(仅临时排查用)。

内容的提问来源于stack exchange,提问作者Sameer Kulkarni

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 11:05:23