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

React useState管理嵌套formData时表单输入更新异常问题

问题根因
  • 字段映射不匹配:两个姓名输入框的name属性值为firstName、lastName,和嵌套在fullName下的state路径不匹配。更新逻辑直接将[name]: value挂载到state根层级,只会新增根属性,不会修改fullName内部的字段。
  • 不可变更新缺失:就算name配置正确,直接修改嵌套对象属性不符合React state的不可变更新要求,会导致状态更新不触发视图同步。
  • 受控组件值绑定错位:输入框的value始终绑定的是从未被更新的formData.fullName.firstName/lastName(初始为空字符串),每次输入触发重渲染后输入框值被重置为空,因此表现为每次只能存入单个输入字符。
  • 附加笔误:所有input标签的类型属性写错,原代码写的是text="text",正确属性为type="text"。

问题表现参考截图:
问题截图

修正步骤
  1. 修正input标签属性:将类型属性改为正确的type,同时将两个姓名输入框的name属性改为和state层级对应的fullName.firstName、fullName.lastName,和根层级字段做区分。
  2. 重写状态更新逻辑,针对嵌套字段做上层对象的浅拷贝,保证不可变更新。
修正后完整代码

状态定义(原定义无需修改)

const [formData, setFormData] = useState({
  fullName: {
    firstName: "",
    lastName: "",
  },
  email: "",
  password: "",
  confirmPassword: "",
});

更新后的handleChange方法

const handleChange = (event) => {
  const { value, name } = event.target;
  
  // 处理fullName下的嵌套字段
  if (name.startsWith("fullName.")) {
    const nestedField = name.split(".")[1];
    setFormData((prevFormData) => ({
      ...prevFormData,
      fullName: {
        ...prevFormData.fullName,
        [nestedField]: value,
      },
    }));
    return;
  }

  // 处理根层级字段
  setFormData((prevFormData) => ({
    ...prevFormData,
    [name]: value,
  }));
};

修正后的JSX片段

<div className="App">
  <form onSubmit={onSubmit}>
    <h1>Submit Form Nested Object UseState</h1>

    <input
      type="text"
      placeholder="First Name"
      name="fullName.firstName"
      value={formData.fullName.firstName}
      onChange={handleChange}
    />
    <input
      type="text"
      placeholder="Last Name"
      name="fullName.lastName"
      value={formData.fullName.lastName}
      onChange={handleChange}
    />
    <input
      type="email"
      placeholder="email"
      name="email"
      value={formData.email}
      onChange={handleChange}
    />
    <input
      type="password"
      placeholder="password"
      name="password"
      value={formData.password}
      onChange={handleChange}
    />
    <input
      type="password"
      placeholder="confirm Password"
      name="confirmPassword"
      value={formData.confirmPassword}
      onChange={handleChange}
    />
    <button>Submit</button>
  </form>
  {JSON.stringify(formData, null, 2)}
</div>

如果后续有更多层级的嵌套状态,可以把更新逻辑抽成通用的嵌套取值/赋值工具函数,不用为每个嵌套层级单独写判断。

内容的提问来源于stack exchange,提问作者PAUL

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 08:09:20