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

TypeScript中onChange更新对象数组状态的类型报错问题

问题根因

你遇到的报错和逻辑问题来自两点:

  • TypeScript静态类型检查默认认为DOM dataset 上的属性值是 string | undefined 类型,它无法感知你在JSX中一定给元素绑定了data-id属性,所以直接拿id当数组索引时,会抛出「undefined不能作为索引类型」的错误。
  • 你为两个字段单独写change处理函数存在冗余逻辑,完全可以合并为一个通用处理函数,降低维护成本。
可直接运行的修复方案

1. 替换原有两个独立的change处理函数

用通用字段更新逻辑替代,同时解决TS类型报错:

interface GameObj {
  title: string;
  steamUrl: string;
}

// 组件内的通用change处理函数
const handleFieldChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
  const { name, value, dataset } = e.target;
  // 类型收窄:排除data-id不存在的异常场景,解决TS的undefined类型报错
  const rawId = dataset.id;
  if (rawId === undefined) return;
  // data-id是字符串类型,转成数字作为数组索引
  const targetIndex = Number(rawId);

  setList(prevList => {
    // 索引合法性校验,避免数组越界
    if (targetIndex < 0 || targetIndex >= prevList.length) return prevList;
    // 不可变更新:不直接修改原状态,返回新的数组和对象引用,保证React能正常检测变化
    return prevList.map((item, idx) => {
      if (idx !== targetIndex) return item;
      return {
        ...item,
        [name]: value
      } satisfies GameObj;
    });
  });
};

2. 调整JSX中表单元素的绑定规则

确保每个输入框的name属性值和GameObj接口的字段名完全一致,data-id绑定当前条目的数组索引(转成字符串):

{list.map((item, index) => (
  <div key={index} className="form-item">
    <input
      type="text"
      name="title" // 和GameObj的title字段名完全对应
      data-id={String(index)}
      value={item.title}
      onChange={handleFieldChange}
      placeholder="输入游戏名称"
    />
    <input
      type="text"
      name="steamUrl" // 和GameObj的steamUrl字段名完全对应
      data-id={String(index)}
      value={item.steamUrl}
      onChange={handleFieldChange}
      placeholder="输入Steam商店链接"
    />
    <button onClick={() => handleDeleteItem(index)}>删除该条目</button>
  </div>
))}
注意事项
  • 不要直接修改原状态数组/数组里的对象,必须通过返回新引用的方式更新状态,否则React不会触发重渲染,新增/删除/修改逻辑会出现视图不更新的问题。
  • 如果你确实需要保留两个独立的处理函数,只需要在每个函数里做同样的id非空判断、类型转换,更新时固定写死要修改的字段即可,比如handleTitleChange里更新时写{ ...item, title: value },不需要动态取name。
  • 渲染列表时如果条目没有唯一业务ID,用数组索引当key在这个新增删除的场景下不会有问题,如果后续有排序、拖拽需求再替换成唯一ID即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:21:38