React中Ant Design Select设选中值后仍触发表单校验如何解决
问题产生原因
- 核心错误是字段名不匹配:你给「To Currency」表单项的
Form.Item设置的name属性是toCurrency(驼峰命名),但在useEffect里调用form.setFieldsValue时,给该字段赋值用的key是to_currency(下划线命名)。Ant Design Form的字段存储完全和name属性绑定,名字对不上的话,你调用set方法赋的值根本存不到对应表单项里,自然校验的时候会认为该字段为空。 - 其次是表单状态冲突:Antd 4.x的Form会自动接管内部表单控件的状态,自动给子组件注入
value和onChange属性实现双向绑定。你额外给Select组件绑定了自定义的toCurrency状态作为value/defaultValue,还单独维护了一份state,会导致视觉显示的值和Form内部存储的真实值脱节——你看到Select显示CAD,是因为你自己绑的state生效了,但Form内部存的这个字段值还是空的,提交校验自然会触发必填提示。 - 额外的无效属性:你写的
initialvalue属性拼写错误,正确写法是驼峰的initialValue,而且这个属性只在组件首次挂载时生效,你异步拉取数据后再传这个值根本不会触发更新,属于无效代码;给Select加的onLoad也不是组件的原生API,不会生效。
正确修复步骤
- 统一字段命名:把「To Currency」对应的
Form.Item的name属性从toCurrency改成to_currency,和setFieldsValue里的字段名完全对齐。 - 移除冗余的状态绑定:删掉单独维护的
toCurrencystate(其他几个Input绑定的自定义value/onChange如果没有特殊业务需求也建议删掉,统一交给Form管理),不要给Select组件传value、defaultValue、onLoad这类会和Form状态冲突的属性,值的同步完全交给Form接管。 - 保留现有
useEffect里的form.setFieldsValue逻辑即可,不需要额外调用setState同步值,只要字段名匹配,Form会自动把值同步给Select组件,显示正确的选中项,同时校验规则也能正常读取到字段值。
修复后的核心代码示例
{ currencyListLoading ? <Loader message={"Loading Currency List"} description={"Listing all currency data"} type={"success"}/> : <Form.Item name="to_currency" // 修正为和setFieldsValue一致的字段名 label="To Currency" rules={[{ required: true, message: 'Please, select a secondary currency' }]} > <Select placeholder="Select a option and change input text above" allowClear onChange={value => { // 如有业务需要获取选中值,直接在回调里处理即可,无需单独维护state同步Form值 }} > <Option key={0} value="0">None</Option> {currencyList && currencyList.length > 0 && currencyList.map((currency) => { return ( <Option key={currency?.currency_code} value={currency?.currency_code}>{currency?.currency_code}</Option> ) })} </Select> </Form.Item> }
注意:Antd 4.x Form本身自带完整的状态管理能力,非特殊联动场景不要给Form.Item下的表单控件手动绑定value/onChange,也不要维护和Form字段重复的独立state,避免出现双数据源不同步的问题。所有表单值的读写优先通过form实例的
setFieldsValue/getFieldsValue方法实现。
内容的提问来源于stack exchange,提问作者Saswat
相关产品推荐
相关产品推荐

