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

Material UI+React Hook Form:禁用复选框无法提交问题求助

表单提交时禁用必填复选框导致react-hook-form验证失败的问题解决

我使用Next.js + TypeScript,搭配react-hook-form和Material-UI实现表单提交时禁用所有字段的功能,目前文本框、选择器和单选框都正常生效,但必填复选框出现问题——给<FormControl>添加disabled={isSubmitting}属性后,react-hook-form不再识别复选框的值,直接标记为必填错误。

相关组件代码如下:

const id = "vehicles";
const OPTIONS = ["bike", "car", "truck", "van"];

export const Vehicles = (): JSX.Element => {
  const {
    register,
    formState: { errors }
  } = useFormContext();
  const error = get(errors, id);

  return (
    <CheckboxMultiFieldInput label="Vehicles" error={error} required>
      {OPTIONS.map(startCase).map((option: string) => (
        <CheckBoxOptionMap
          value={option}
          label={option}
          key={option}
          registerProps={register(id, { required: true })}
        />
      ))}
    </CheckboxMultiFieldInput>
  );
};

export const CheckBoxOptionMap = ({
  value,
  label,
  registerProps
}: CheckboxOptionMapInterface) => {
  // Also can't submit with the disabled prop here instead
  // const {
  //   formState: { isSubmitting }
  // } = useFormContext();
  return (
    <FormControlLabel
      value={value}
      control={<Checkbox {...registerProps} />}
      label={label}
      aria-label={`${label}-option-${value}`}
      // disabled={isSubmitting}
    />
  );
};

export const CheckboxMultiFieldInput = ({
  children,
  label,
  error,
  required
}: CheckboxMultiFieldInterface): JSX.Element | null => {
  // Cannot submit anymore once this disabled prop is added
  // const {
  //   formState: { isSubmitting }
  // } = useFormContext();

  if (!children || children.length === 0) {
    return null;
  }

  return (
    <div className="inputBox">
      <FormControl
        error={error !== undefined}
        required={required}
        // disabled={isSubmitting}
      >
        <FormLabel>{label}</FormLabel>
        {children}
        {error && (
          <FormHelperText id={`${label}-helper-text`}>
            {error.message || error.type}
          </FormHelperText>
        )}
      </FormControl>
    </div>
  );
};

问题根源

Material-UI的<FormControl>添加disabled属性后,会批量禁用内部所有表单控件,但react-hook-form默认不会收集禁用字段的值,导致提交时验证逻辑认为复选框未被勾选,触发必填错误。

解决办法

方案1:单独控制复选框禁用状态并强制RHF收集值

这种方式不需要修改整体结构,只需调整两处代码:

  1. 更新Vehicles组件中register的配置,添加disabled: false强制RHF收集字段值:
    register(id, { required: true, disabled: false })
    
  2. 修改CheckBoxOptionMap组件,获取isSubmitting状态并直接给<Checkbox>添加禁用属性:
    export const CheckBoxOptionMap = ({
      value,
      label,
      registerProps
    }: CheckboxOptionMapInterface) => {
      const { formState: { isSubmitting } } = useFormContext();
      return (
        <FormControlLabel
          value={value}
          control={<Checkbox {...registerProps} disabled={isSubmitting} />}
          label={label}
          aria-label={`${label}-option-${value}`}
        />
      );
    };
    
  3. 确保<FormControl>上的disabled属性保持注释或移除,避免批量禁用影响字段收集。

方案2:使用Controller组件接管字段控制

如果需要更灵活的字段控制,推荐用react-hook-form的Controller组件包裹复选框,明确指定即使控件禁用也保留值的收集逻辑:

// 修改Vehicles组件
export const Vehicles = (): JSX.Element => {
  const {
    control,
    formState: { errors, isSubmitting }
  } = useFormContext();
  const error = get(errors, id);

  return (
    <CheckboxMultiFieldInput label="Vehicles" error={error} required>
      {OPTIONS.map(startCase).map((option: string) => (
        <Controller
          name={id}
          control={control}
          rules={{ required: true }}
          render={({ field }) => (
            <FormControlLabel
              value={option}
              control={<Checkbox {...field} disabled={isSubmitting} />}
              label={option}
              aria-label={`${option}-option-${option}`}
            />
          )}
          key={option}
        />
      ))}
    </CheckboxMultiFieldInput>
  );
};

关键说明

  • react-hook-form的register方法中,disabled选项是控制是否收集字段值的开关,设置为false可以强制收集,不受控件本身disabled属性的影响。
  • 避免用<FormControl>的disabled批量禁用控件,因为这会让RHF默认忽略这些字段的值,导致验证失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 17:57:20