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

React中如何用单个State管理200+输入框?解决值同步问题

如何用单个State管理200+列表输入框

问题背景

我正在开发一个包含200多个列表输入框的项目,想知道是否可以用单个state来管理它们。当前代码存在问题:输入内容时所有输入框会显示相同值,以下是当前使用的代码:

当前代码

List组件

import { useState } from "react";
import Item from "../Components/Item";

const initialState={
  input:''
}

const List = () => {
  const [values,setValues]=useState(initialState)

  const handleChange=(e)=>{
    setValues({
      ...values,[e.target.name]:e.target.value
    })
  }

  return (
    <div className="container">
      <div className="listhead">
        <h3 className="text-center">Price List-2022</h3>
        <table className="table table-bordered border-dark table-hover text-center">
          <thead className="bg-success text-white table-bordered border-dark">
            <tr>
              <th>S.No</th>
              <th>Item</th>
              <th>Price</th>
              <th>Qty</th>
              <th>Total</th>
            </tr>
          </thead>
          <Item
            product="bomb"
            name="input"
            price="50"
            value={values.input}
            handleChange={handleChange}
          />
          <Item
            product="chakkar"
            name="input"
            price="100"
            value={values.input}
            handleChange={handleChange}
          />
        </table>
      </div>
    </div>
  );
};
export default List;

Item子组件

const Item = ({name,product,price,value,handleChange}) => {
    return (
    <tbody>
      <tr>
        <th>1</th>
        <th>{product}</th>
        <th>{price}</th>
        <th className="w-25">
          <input
            name={name}
            value={value}
            onChange={handleChange}
            type='number'
          />
        </th>
        <th> </th>
      </tr>
    </tbody>
  );
};
export default Item;

问题原因

所有输入框共用了同一个name属性值input,并且绑定的都是values.input这个state字段,导致每次输入时所有输入框读取的是同一个state值,出现内容同步的问题。

可行解决方案

方法一:对象型State+唯一name字段

给每个输入框分配唯一的name(比如产品名称、唯一ID),用对象型state存储每个输入框的值,适合需要单独管理每个输入值的场景:

修改后的List组件

import { useState } from "react";
import Item from "../Components/Item";

// 200个产品建议从外部数据源导入,避免硬编码
const initialItems = [
  { product: "bomb", price: "50" },
  { product: "chakkar", price: "100" },
  // ...其余产品
];

// 生成初始state,key为产品名,值为空字符串
const initialState = initialItems.reduce((acc, item) => {
  acc[item.product] = "";
  return acc;
}, {});

const List = () => {
  const [values, setValues] = useState(initialState);

  const handleChange = (e) => {
    setValues({
      ...values,
      [e.target.name]: e.target.value
    });
  };

  return (
    <div className="container">
      <div className="listhead">
        <h3 className="text-center">Price List-2022</h3>
        <table className="table table-bordered border-dark table-hover text-center">
          <thead className="bg-success text-white table-bordered border-dark">
            <tr>
              <th>S.No</th>
              <th>Item</th>
              <th>Price</th>
              <th>Qty</th>
              <th>Total</th>
            </tr>
          </thead>
          {/* 循环渲染Item,避免重复编写200次 */}
          {initialItems.map((item, index) => (
            <Item
              key={item.product}
              product={item.product}
              name={item.product} // 用产品名作为唯一标识
              price={item.price}
              value={values[item.product]}
              handleChange={handleChange}
              serialNumber={index + 1}
            />
          ))}
        </table>
      </div>
    </div>
  );
};
export default List;

修改后的Item组件

const Item = ({ name, product, price, value, handleChange, serialNumber }) => {
  const total = parseInt(value) * parseInt(price) || 0;

  return (
    <tbody>
      <tr>
        <th>{serialNumber}</th>
        <th>{product}</th>
        <th>{price}</th>
        <th className="w-25">
          <input
            name={name}
            value={value}
            onChange={handleChange}
            type='number'
            min="0"
          />
        </th>
        <th>{total}</th>
      </tr>
    </tbody>
  );
};
export default Item;

方法二:数组型State管理完整项数据

如果需要同时管理产品的价格、数量等完整信息,可以用数组型state存储每个项的全部数据,每个数组元素是包含产品信息的对象:

修改后的List组件

import { useState } from "react";
import Item from "../Components/Item";

const initialItems = [
  { product: "bomb", price: "50", qty: "" },
  { product: "chakkar", price: "100", qty: "" },
  // ...其余产品
];

const List = () => {
  const [items, setItems] = useState(initialItems);

  const handleChange = (index, value) => {
    // 复制数组并更新对应索引的项
    const updatedItems = [...items];
    updatedItems[index].qty = value;
    setItems(updatedItems);
  };

  return (
    <div className="container">
      <div className="listhead">
        <h3 className="text-center">Price List-2022</h3>
        <table className="table table-bordered border-dark table-hover text-center">
          <thead className="bg-success text-white table-bordered border-dark">
            <tr>
              <th>S.No</th>
              <th>Item</th>
              <th>Price</th>
              <th>Qty</th>
              <th>Total</th>
            </tr>
          </thead>
          {items.map((item, index) => (
            <Item
              key={item.product}
              item={item}
              serialNumber={index + 1}
              onQtyChange={(value) => handleChange(index, value)}
            />
          ))}
        </table>
      </div>
    </div>
  );
};
export default List;

修改后的Item组件

const Item = ({ item, serialNumber, onQtyChange }) => {
  const total = parseInt(item.qty) * parseInt(item.price) || 0;

  return (
    <tbody>
      <tr>
        <th>{serialNumber}</th>
        <th>{item.product}</th>
        <th>{item.price}</th>
        <th className="w-25">
          <input
            value={item.qty}
            onChange={(e) => onQtyChange(e.target.value)}
            type='number'
            min="0"
          />
        </th>
        <th>{total}</th>
      </tr>
    </tbody>
  );
};
export default Item;

方法三:useReducer管理大规模复杂State

当输入项数量多、更新逻辑复杂时,用useReducer比useState更易维护,将更新逻辑集中在reducer函数中:

List组件使用useReducer

import { useReducer } from "react";
import Item from "../Components/Item";

const initialItems = [
  { product: "bomb", price: "50", qty: "" },
  { product: "chakkar", price: "100", qty: "" },
  // ...其余产品
];

// 定义reducer处理状态更新
const itemReducer = (state, action) => {
  switch (action.type) {
    case "UPDATE_QTY":
      const updatedState = [...state];
      updatedState[action.index].qty = action.value;
      return updatedState;
    default:
      return state;
  }
};

const List = () => {
  const [items, dispatch] = useReducer(itemReducer, initialItems);

  return (
    <div className="container">
      <div className="listhead">
        <h3 className="text-center">Price List-2022</h3>
        <table className="table table-bordered border-dark table-hover text-center">
          <thead className="bg-success text-white table-bordered border-dark">
            <tr>
              <th>S.No</th>
              <th>Item</th>
              <th>Price</th>
              <th>Qty</th>
              <th>Total</th>
            </tr>
          </thead>
          {items.map((item, index) => (
            <Item
              key={item.product}
              item={item}
              serialNumber={index + 1}
              onQtyChange={(value) => dispatch({
                type: "UPDATE_QTY",
                index,
                value
              })}
            />
          ))}
        </table>
      </div>
    </div>
  );
};
export default List;

Item组件与方法二中的实现一致即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 02:05:58