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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:47:05