ReactJs与React-Hook-Form:下拉框选Other时输入框显隐异常问题
问题分析
你的问题出在类型不匹配:下拉框选项的value是字符串类型(比如"5"),但你定义的defaultBrandId是数字类型5。当用户重新选择"Other"时,getValues().brandId拿到的是字符串"5",和数字5比较结果为false,所以showBrandInput不会被设为true。
另外,用watch('brandId')作为useEffect的依赖存在冗余,直接监听watch返回的值更高效。
修复方案
以下两种方案任选其一即可:
方案一:统一类型(推荐)
把defaultBrandId改成字符串类型,和下拉框选项的value保持一致,同时调整类型定义和监听逻辑:
// 1. 修改类型定义,brandId改为字符串 type Car = { brandId: string, brand: string } // 2. defaultBrandId改为字符串"5" const defaultBrandId = "5"; // 'Other' // 3. 提前监听brandId的值 const brandId = watch('brandId'); // 4. 简化useEffect逻辑 useEffect(() => { setShowBrandInput(brandId === defaultBrandId); }, [brandId]);
方案二:类型转换比较
如果不想修改defaultBrandId的类型,就在比较时把表单值转换为数字:
useEffect(() => { const currentBrandId = Number(getValues().brandId); setShowBrandInput(currentBrandId === defaultBrandId); }, [watch('brandId')]);
完整修复代码(方案一)
export default function Test() { type Car = { brandId: string, brand: string } const defaultBrandId = "5"; // 'Other' const [showBrandInput, setShowBrandInput] = useState<boolean>(true); const { register, handleSubmit, setValue, watch} = useForm<Car>(); const brandId = watch('brandId'); useEffect(() => { fetchCarBrands(); }, []) useEffect(() => { setShowBrandInput(brandId === defaultBrandId); }, [brandId]); function fetchCarBrands() { // API call to get select list data // Set default select list value to 'Other' setValue("brandId", defaultBrandId); } function onSubmit() { alert("form submitted"); } return ( <> <Form onSubmit={handleSubmit(onSubmit)} noValidate> <Div className="mb-4"> <FormLabel>Brand</FormLabel> <Row> <Col> <Form.Select {...register("brandId")}> <option value="1">Chevy</option> <option value="2">Ford</option> <option value="3">Honda</option> <option value="4">Toyota</option> <option value="5">Other</option> </Form.Select> </Col> <Col> {showBrandInput && <Form.Control type="text" {...register("brand")} /> } </Col> </Row> </Div> <Button type="submit" className="btn-dk-blue"> Submit </Button> </Form> </> ) }
额外优化建议
- 提前解构
watch('brandId')的返回值,避免在useEffect中重复调用watch - 保持表单字段类型和输入控件的value类型一致,能减少很多隐性的类型问题
内容的提问来源于stack exchange,提问作者PixelPaul
相关产品推荐
相关产品推荐

