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

TypeScript动态添加输入字段组仅返回输入首字符问题排查

解决React动态输入框仅能获取第一个字符的问题

你的问题核心是闭包陷阱:handleUser函数里直接引用了组件渲染时的info状态,当连续输入时,函数捕获的还是初始的旧状态,导致每次更新都只基于第一次输入前的状态,所以只能看到输入的第一个字符。你尝试的setInfo((prev) => ({ ...prev, [name]: value }))报错,是因为把数组当成对象来解构更新了,info是数组类型,不能这么处理。

修正后的代码

import { useState } from 'react';

const UserForm = () => {
  const [info, setInfo] = useState([{
    name: "",
    email: "",
    age: 0,
  }])

  const handleAddAnotherUser = () => {
    setInfo(prevInfo => [...prevInfo, {
      name: "",
      email: "",
      age: 0,
    }])
  }

  const handleUser = (i: number, event: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = event.target;
    // 使用函数式更新获取最新状态,避免闭包陷阱
    setInfo(prevInfo => {
      // 拷贝原数组,避免直接修改原状态
      const newInfo = [...prevInfo];
      // 拷贝要修改的用户对象,保证状态不可变性
      newInfo[i] = { ...newInfo[i], [name]: name === 'age' ? Number(value) : value };
      return newInfo;
    });
  }

  return (
    <>
      {info.map((item, i) => (
        // 给列表元素添加唯一key,React列表渲染必须项
        <div key={i}>
          <input
            id={`name-${i}`} // 每个输入框id要唯一,避免冲突
            name="name"
            type="text"
            placeholder="Joe Bloggs"
            value={item.name}
            onChange={(event) => handleUser(i, event)}
          />
          <input
            id={`email-${i}`}
            name="email"
            type="email"
            placeholder="hello@email.com"
            value={item.email}
            onChange={(event) => handleUser(i, event)}
          />
          <input
            id={`age-${i}`}
            name="age"
            type="number"
            placeholder="34"
            value={item.age}
            onChange={(event) => handleUser(i, event)}
          />
        </div>
      ))}
      <button onClick={handleAddAnotherUser}>Add Another</button>
    </>
  )
}

export default UserForm;

关键修正点

  • 函数式状态更新:用setInfo(prevInfo => ...)代替直接引用info,确保每次更新都能拿到最新的状态,解决闭包导致的旧状态问题。
  • 保证状态不可变性:修改用户对象时创建新对象{ ...newInfo[i], [name]: ... },而非直接修改原对象,符合React状态更新的最佳实践。
  • 唯一标识处理:给每个输入框设置唯一id(如name-${i})避免冲突;列表元素添加key,帮助React高效渲染列表。
  • 类型适配:针对age字段将输入值转为数字类型,避免字符串存入状态导致的类型不一致问题。

内容的提问来源于stack exchange,提问作者KG 01001011 01000111

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 03:22:56