Ant Design Form中Form.Item带name时onBlur无法setValue的原因
问题:Form.Item设置name属性后,onBlur中setValue无法生效?
我在执行onBlur函数时遇到无法setValue的错误,但移除Form.Item的name属性后功能恢复正常。请问为何设置name属性时会出现该问题?
代码如下:
const App = () => { const [valuess, setValue] = useState(""); const onBlur = () => { let str = valuess; str = str .normalize("NFD") .replace(/[\u0300-\u036f]/g, "") .replace(/[đĐ]/g, (m) => (m === "đ" ? "d" : "D")) .toUpperCase(); setValue(str); console.log(str); }; return ( <Form> <Form.Item label="Username" name="fullname" rules={[ { required: true, message: "Please input your username!" } ]} > <Input onChange={(e) => setValue(e.target.value)} value={valuess} onBlur={onBlur} /> </Form.Item> </Form> ); }; export default App;
原因分析
当你给Form.Item设置name属性时,Ant Design的Form组件会自动接管该字段的状态管理——它会用内部的表单状态(通过useForm创建的实例)来维护字段值,而你自己用useState声明的valuess和Form的内置状态产生了冲突。
具体过程:
- 你在
onChange里更新自己的valuess,同时Form也会因为name的存在,同步更新它的内部状态; - 当
onBlur触发时,你调用setValue更新valuess,但Form会在这个时机(比如字段失焦时的校验或状态同步)用它的内部值覆盖掉你设置的valuess,导致输入框值没有变化,看起来像是setValue没生效。
解决办法
方法1:改用Form内置状态管理(推荐)
直接用Ant Design Form的状态管理能力,抛弃自己的useState,统一通过form实例操作字段值:
import { Form, Input, useForm } from 'antd'; const App = () => { const [form] = useForm(); const onBlur = () => { let str = form.getFieldValue('fullname'); // 处理字符串 str = str .normalize("NFD") .replace(/[\u0300-\u036f]/g, "") .replace(/[đĐ]/g, (m) => (m === "đ" ? "d" : "D")) .toUpperCase(); // 用form实例更新字段值 form.setFieldValue('fullname', str); console.log(str); }; return ( <Form form={form}> <Form.Item label="Username" name="fullname" rules={[ { required: true, message: "Please input your username!" } ]} > {/* 不用手动绑定value和onChange,Form.Item会自动处理 */} <Input onBlur={onBlur} /> </Form.Item> </Form> ); }; export default App;
方法2:保留自己的state,同步Form状态
如果一定要用自己的useState维护值(比如有特殊业务场景),需要在更新自己state的同时,同步更新Form的内置状态:
import { Form, Input, useForm } from 'antd'; import { useState } from 'react'; const App = () => { const [form] = useForm(); const [valuess, setValue] = useState(""); const handleChange = (e) => { const value = e.target.value; setValue(value); // 同步到Form的内置状态 form.setFieldValue('fullname', value); }; const onBlur = () => { let str = valuess; str = str .normalize("NFD") .replace(/[\u0300-\u036f]/g, "") .replace(/[đĐ]/g, (m) => (m === "đ" ? "d" : "D")) .toUpperCase(); setValue(str); // 同时更新Form的内置状态,避免被覆盖 form.setFieldValue('fullname', str); console.log(str); }; return ( <Form form={form} initialValues={{ fullname: valuess }}> <Form.Item label="Username" name="fullname" rules={[ { required: true, message: "Please input your username!" } ]} > <Input onChange={handleChange} value={valuess} onBlur={onBlur} /> </Form.Item> </Form> ); }; export default App;
内容的提问来源于stack exchange,提问作者phu quang
相关产品推荐
相关产品推荐

