基于react-hook-form实现单选按钮再次点击取消选中的问题
解决方案
直接利用react-hook-form的watch和setValue管理单选按钮状态,抛弃自定义useState,既解决切换失效问题,又保留RHF的性能优势:
import { useForm } from "react-hook-form"; import "./styles.css"; export default function App() { const { register, formState: { errors }, handleSubmit, setValue, watch, } = useForm({ defaultValues: { TEST: "", // 初始空值表示未选中任何选项 TEST_NAME: "" } }); const currentTestValue = watch("TEST"); // 统一处理单选按钮点击逻辑 const handleRadioClick = (value) => { if (currentTestValue === value) { // 已选中状态下点击,取消选中 setValue("TEST", ""); } else { // 选中新选项 setValue("TEST", value); } }; return ( <div className="App"> <input className="input formInput" {...register("TEST_NAME", { validate: (value, formValues) => { return value !== "" || formValues.TEST === "" || "请填写名称"; }, })} /> {errors.TEST_NAME && <span>{errors.TEST_NAME.message}</span>} <span> type1</span> <input type="radio" value={1} onClick={() => handleRadioClick(1)} checked={currentTestValue === 1} {...register("TEST", { validate: (value, formValues) => { return value !== "" || formValues.TEST_NAME === "" || "请选择假期类型"; }, })} /> <span> type2</span> <input type="radio" value={0.5} onClick={() => handleRadioClick(0.5)} checked={currentTestValue === 0.5} {...register("TEST", { validate: (value, formValues) => { return value !== "" || formValues.TEST_NAME === "" || "请选择假期类型"; }, })} /> {errors.TEST && <span>{errors.TEST.message}</span>} </div> ); }
关键改动说明:
- 移除自定义
test1、test2状态,改用watch("TEST")获取当前选中值,完全依赖RHF的表单状态管理,避免不必要的组件重渲染。 - 统一的
handleRadioClick函数处理所有单选按钮点击:判断当前值是否等于点击的选项值,相等则清空,否则设置为该值,自动处理单选按钮的互斥逻辑(选中新选项时旧选项自动取消)。 - 单选按钮的
checked状态直接通过currentTestValue === 对应value判断,无需手动维护。 - 保留原有验证逻辑,调整提示文案为中文(可按需改回英文)。
修改后效果:
- 可直接在type1和type2之间切换,无需先取消当前选中项。
- 再次点击已选中的单选按钮会取消选中状态。
- 完全利用react-hook-form的状态管理,避免额外重渲染,发挥其性能优势。
内容的提问来源于stack exchange,提问作者JungsuRy
相关产品推荐
相关产品推荐

