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

React中如何向数组内添加对象?useState状态管理求助

解决React中useState管理数组内对象的问题

核心问题分析

你的代码存在几个关键问题:

  • 未在info状态中维护items数组,而是直接将单个商品字段(itemName等)存到info根节点,导致每次输入都会覆盖之前的值
  • 用单独的itemForm.num控制商品数量,和实际数据结构脱节,无法关联每个商品的输入值
  • 删除/添加逻辑只修改数量,没有同步更新实际的商品数组

修复后的完整代码

import { useState } from 'react';

export default function YourComponent() {
  // 初始化符合期望结构的state,包含默认的空商品项
  const [info, setInfo] = useState({
    company: "",
    companyAdress: "",
    items: [{ itemName: "", itemQuantity: "", itemPrice: "" }]
  });

  // 添加新商品项
  const handleAddItem = (e) => {
    e.preventDefault();
    setInfo(prev => ({
      ...prev,
      items: [...prev.items, { itemName: "", itemQuantity: "", itemPrice: "" }]
    }));
  };

  // 删除指定索引的商品项,保留至少一个商品
  const handleRemoveItem = (e, index) => {
    e.preventDefault();
    if (info.items.length <= 1) return;
    setInfo(prev => ({
      ...prev,
      items: prev.items.filter((_, i) => i !== index)
    }));
  };

  // 更新指定索引的商品字段
  const handleItemChange = (index, field, value) => {
    setInfo(prev => ({
      ...prev,
      items: prev.items.map((item, i) => 
        i === index ? { ...item, [field]: value } : item
      )
    }));
  };

  return (
    <div>
      <label>Company</label>
      <input 
        value={info.company}
        onChange={(e) => setInfo({ ...info, company: e.target.value })} 
        placeholder="Company"
      />

      <label>Company Address</label>
      <input 
        value={info.companyAdress}
        onChange={(e) => setInfo({ ...info, companyAdress: e.target.value })} 
        placeholder="Adresse"
      />

      <ul className="space-y-3">
        {info.items.map((item, index) => (
          <li key={index}>
            <div>
              <input 
                value={item.itemName}
                onChange={(e) => handleItemChange(index, "itemName", e.target.value)} 
                placeholder="itemName:" 
              />
              <input 
                type="number"
                value={item.itemQuantity}
                onChange={(e) => handleItemChange(index, "itemQuantity", e.target.value)} 
                placeholder="Quantity:"
              />
              <input 
                type="number"
                value={item.itemPrice}
                onChange={(e) => handleItemChange(index, "itemPrice", e.target.value)} 
                placeholder="Price:"
              />

              <button onClick={(e) => handleRemoveItem(e, index)}>Enlever</button>
            </div>
          </li>
        ))}
      </ul>
      {/* 把添加按钮放到列表外,避免重复渲染 */}
      <button onClick={handleAddItem}>+ Add New Item</button>
    </div>
  );
}

关键修改说明

  • 统一状态管理:将items数组直接纳入info状态,完全匹配你期望的数据结构
  • 精准更新商品项:通过handleItemChange函数,根据索引和字段名更新对应商品的属性,避免覆盖其他项
  • 正确的增删逻辑:
    • 添加商品时,复制原数组并追加新的空商品对象
    • 删除商品时,过滤掉指定索引的项,同时限制至少保留一个商品
  • 绑定输入值:每个输入框都绑定对应商品项的字段值,实现双向关联

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 18:50:29