如何在选中其他复选框时取消勾选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) ); } }} />
关键改动说明
- 将判断
['none'].includes(field.value)改为field.value?.includes('none'),正确检测当前选中值中是否包含'none' - 优化非None选项勾选时的逻辑:如果当前包含'none',直接替换为当前选项(自动取消None);否则添加当前选项到数组中
内容的提问来源于stack exchange,提问作者Stykgwar
相关产品推荐
相关产品推荐

