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

React中如何让映射数组内的输入框值独立修改

解决React商品数量输入框同步变化的问题

你遇到的问题根源是所有商品项共享了同一个amount状态变量,所以修改任意一个输入框都会让所有输入框同步更新。要实现独立控制每个商品的数量,需要用对象类型的状态,以商品ID为键来存储对应商品的数量。

下面是修改后的完整代码,关键改动已标注:

import React, { useState } from "react";
import "./produce.css";
import produce from "../produce.json";
import { MdArrowDropUp, MdArrowDropDown } from "react-icons/md";

const Produce = () => {
  // 1. 将单个状态改为对象,以商品id为键存储数量,初始值为空(或提前初始化所有商品为0)
  const [amounts, setAmounts] = useState({});

  // 2. 修改增减函数,接收商品id,只更新对应商品的数量
  const handleIncrease = (id) => {
    setAmounts(prev => {
      const currentAmount = prev[id] || 0;
      return { ...prev, [id]: currentAmount < 20 ? currentAmount + 1 : 20 };
    });
  };

  const handleDecrease = (id) => {
    setAmounts(prev => {
      const currentAmount = prev[id] || 0;
      return { ...prev, [id]: currentAmount > 0 ? currentAmount - 1 : 0 };
    });
  };

  // 3. 修改输入框change事件,针对当前商品id更新数量,同时做边界和类型处理
  const handleChange = (e, id) => {
    let value = Number(e.target.value);
    // 确保输入是有效数字,且在0-20范围内
    if (isNaN(value)) value = 0;
    if (value < 0) value = 0;
    if (value > 20) value = 20;
    setAmounts(prev => ({ ...prev, [id]: value }));
  };

  return (
    <div className="produce">
      {produce.map((item) => {
        // 4. 每个输入框绑定对应商品id的数量,默认值为0
        const itemAmount = amounts[item.id] || 0;
        return (
          <div className="produce_item" key={item.id}>
            <img className="item_img" src={item.img} />
            <div className="produce_explain">
              <div className="produce_explain1">
                <h3>{item.name}</h3>
                {item.iconOrganic && <img src={item.iconOrganic} />}
              </div>
              <div className="produce_explain2">
                {item.organic === "organic" && <h5>{item.organic}</h5>}
                <div className="produce_weight">
                  <h6>approx.</h6>
                  {item.weight}
                </div>
              </div>
              <div className="produce_price">
                <h3>{item.price} $</h3>
              </div>
            </div>
            <div className="produce_buy">
              <button className="produce_cart">Add to Cart</button>
              <div className="produce_number">
                {/* 5. 点击按钮时传入当前商品id */}
                <button className="produce_increase" onClick={() => handleIncrease(item.id)}>
                  <MdArrowDropUp />
                </button>
                <input
                  type="number" {/* 建议改成number类型,限制输入为数字 */}
                  className="produce_count"
                  value={itemAmount}
                  onChange={(e) => handleChange(e, item.id)}
                  min="0"
                  max="20" {/* 加上输入框的边界限制 */}
                />
                <button className="produce_decrease" onClick={() => handleDecrease(item.id)}>
                  <MdArrowDropDown />
                </button>
              </div>
            </div>
          </div>
        );
      })}
    </div>
  );
};

export default Produce;

关键改动说明:

  • 状态结构调整:从单个amount变量改为amounts对象,每个商品ID对应自己的数量值,实现独立存储。
  • 事件函数适配:增减和输入变更函数都接收商品ID作为参数,只更新对应ID的数量,不影响其他商品。
  • 输入优化:将输入框类型改为number,并添加min和max属性,配合代码中的边界检查,确保输入值合法。
  • 默认值处理:当商品还没有数量记录时,用|| 0默认显示0,避免输入框出现空值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 04:24:22