Antd表单:如何根据同级组件getFieldValue动态修改Select选中值?
解决Ant Design动态表单中Input与Select的自动联动问题
这个需求完全可行,核心是不要依赖initialValue,而是通过Form实例的setFieldsValue方法主动更新Select的表单值。下面是具体实现方案:
关键思路
- 利用
Form.Item的shouldUpdate特性,精准监听当前行Input字段的变化 - 当Input值匹配到手机号、URL或邮箱类型时,调用
form.setFieldsValue直接更新同一行的Select字段值 - 保留用户手动选择非自动匹配类型(如Work、Home)的权限,仅在Input值匹配到特定类型时自动切换
修改后的完整代码
import React from "react"; import "./index.css"; import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons"; import { Button, Form, Input, Select, Space } from "antd"; const { Option } = Select; const options = [ { label: "Work", value: "work" }, { label: "Home", value: "home" }, { label: "Mobile", value: "mobile" }, { label: "URL", value: "url" }, { label: "Email", value: "email" } ]; // 优化正则规则,提升匹配准确性 const validateCurrentInputValueType = (value: string) => { const isMobileRegex = /^1[3-9]\d{9}$/; const isURLRegex = /^(?:https?:\/\/)?(?:www\.)?[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)+[^\s]*$/; const isEmailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; if (isMobileRegex.test(value)) return "mobile"; if (isURLRegex.test(value)) return "url"; if (isEmailRegex.test(value)) return "email"; return null; // 无匹配类型时返回null,避免覆盖用户手动选择项 }; const App: React.FC = () => { const [form] = Form.useForm(); const onFinish = (values: any) => { console.log("Received values of form:", values); }; return ( <Form form={form} name="info-form" onFinish={onFinish} autoComplete="off"> <Form.List name="info"> {(fields, { add, remove }) => ( <> {fields.map(({ key, name, fieldKey, ...restField }) => ( <Space key={key} align="baseline"> <Form.Item label="Details" {...restField} name={[name, "info_input"]} fieldKey={[fieldKey, "info_input"]} > <Input /> </Form.Item> <Form.Item shouldUpdate={(prevValues, currentValues) => prevValues.info?.[name]?.info_input !== currentValues.info?.[name]?.info_input } style={{ marginLeft: 8, width: 100 }} > {({ getFieldValue, setFieldsValue }) => { const currentInputValue = getFieldValue([ "info", name, "info_input" ]); const type = validateCurrentInputValueType(currentInputValue); // 仅当匹配到特定类型时,更新Select值 if (type) { setFieldsValue({ info: form.getFieldValue("info").map((item: any, idx: number) => idx === name ? { ...item, info_select: type } : item ) }); } return ( <Form.Item name={[name, "info_select"]} fieldKey={[fieldKey, "info_select"]} > <Select> {options.map((option) => ( <Option key={option.value} value={option.value}> {option.label} </Option> ))} </Select> </Form.Item> ); }} </Form.Item> <MinusCircleOutlined onClick={() => remove(name)} /> </Space> ))} <Form.Item> <Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />} > Add field </Button> </Form.Item> </> )} </Form.List> <Form.Item> <Button type="primary" htmlType="submit"> Submit </Button> </Form.Item> </Form> ); }; export default App;
核心修改点说明
- 优化正则匹配:将原纯数字正则替换为更符合实际场景的手机号规则,减少误判
- 精准监听变化:给
shouldUpdate传入判断逻辑,仅当前行Input值变化时触发更新,降低不必要的重渲染 - 主动更新表单值:通过
setFieldsValue直接修改对应行的info_select字段,实现Select自动选中目标选项 - 保留手动控制权:仅在Input值匹配到特定类型时自动更新,用户手动选择Work/Home后不会被覆盖
内容的提问来源于stack exchange,提问作者asus
相关产品推荐
相关产品推荐

