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

如何在选中其他复选框时取消勾选None?(react-hook-form+shadcn)

React Hook Form + Shadcn 复选框联动修复

我用React Hook Form和Shadcn实现了一组复选框,包含None、TCET、Others三个选项。目前已实现:选中TCET和Others后点击None,会取消前两者的勾选;但存在问题:选中None后再点击TCET或Others时,无法自动取消None的勾选。

现有代码

表单组件代码

<FormField
  control={form.control}
  name="does_have_assistance"
  render={() => (
    <FormItem>
      <div className="mb-4">
        <FormLabel className="text-base">
          Tech Assitance
        </FormLabel>
      </div>
      {does_have_assistance_choice.map((item) => (
        <FormField
          key={item.id}
          control={form.control}
          name="does_have_assistance"
          render={({ field }) => {
            return (
              <FormItem
                key={item.id}
                className="flex flex-row items-start space-x-3 space-y-0"
              >
                <FormControl>
                  <Checkbox
                    checked={field.value?.includes(item.id)}
                    onCheckedChange={(checked) => {
                      if (item.id === 'none' && checked) {
                        field.onChange(['none']);
                      } else if (item.id !== 'none' && checked) {
                        field.onChange(
                          ['none'].includes(field.value) ? 
                          [...field.value.filter(value => value !== 'none'), item.id] :
                          [...field.value, item.id]
                        );
                      } else {
                        // 取消勾选时移除对应选项
                        field.onChange(
                          field.value?.filter((value: any) => value !== item.id)
                        );
                      }
                    }}
                  />
                </FormControl>

                <FormLabel className="font-normal">
                  {item.label}
                </FormLabel>
              </FormItem>
            );
          }}
        />
      ))}
      <FormMessage />
    </FormItem>
  )}
/>

选项配置(Choices.ts)

export const does_have_assistance_choice = [
  {
    id:'none',
    label:"None"
  },
  {
    id: "tcet",
    label: "TCET",
  },
  {
    id: "others",
    label: "Others",
  },
];

问题原因与修复方案

问题出在非None选项勾选时的判断逻辑:原代码用['none'].includes(field.value)判断当前值是否包含'none',但field.value是数组类型,这个判断永远为false,导致无法移除'none'选项。

修改后的复选框逻辑代码如下:

<Checkbox
  checked={field.value?.includes(item.id)}
  onCheckedChange={(checked) => {
    if (item.id === 'none' && checked) {
      // 选中None时,清空其他选项只保留none
      field.onChange(['none']);
    } else if (item.id !== 'none' && checked) {
      // 选中非None选项时,先移除none再添加当前选项
      const newValue = field.value?.includes('none') 
        ? [item.id] 
        : [...(field.value || []), item.id];
      field.onChange(newValue);
    } else {
      // 取消勾选时移除对应选项
      field.onChange(
        field.value?.filter((value: any) => value !== item.id)
      );
    }
  }}
/>

关键改动说明

  1. 将判断['none'].includes(field.value)改为field.value?.includes('none'),正确检测当前选中值中是否包含'none'
  2. 优化非None选项勾选时的逻辑:如果当前包含'none',直接替换为当前选项(自动取消None);否则添加当前选项到数组中

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 18:23:12