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

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的内置状态产生了冲突。

具体过程:

  1. 你在onChange里更新自己的valuess,同时Form也会因为name的存在,同步更新它的内部状态;
  2. 当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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 23:35:40