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

React.js表格行内输入值与数据库值逐行匹配验证问题

解决方案

问题根源

你之前的写法存在两个核心问题:

  1. onChange事件函数里直接返回JSX不会被React渲染到DOM中,事件回调的返回值无法触发视图更新
  2. 全局状态会让所有行的校验结果绑定在一起,无法实现逐行独立控制

下面提供两种可行的实现方式:


方式一:用对象存储逐行状态

通过对象存储每行的匹配状态,以数据的唯一ID作为key,确保每行状态独立:

import React from "react";
import { useState, useEffect } from "react";
import axios from "axios";

function DailyStock() {
  const [data, setData] = useState([]);
  // 用对象存储每行匹配状态,key为item的唯一标识(比如id)
  const [matchStates, setMatchStates] = useState({});

  useEffect(() => {
    getDailyData();
  }, []);

  const getDailyData = () => {
    axios.get("http://localhost:4000/api/stocks/view-stock").then((res) => {
      const getData = res.data.data;
      setData(getData);
    });
  };

  const handleInputChange = (e, item) => {
    const inputValue = parseInt(e.target.value, 10);
    const expectedValue = item.pQty - item.saleStock;
    // 更新对应行的匹配状态
    setMatchStates(prev => ({
      ...prev,
      [item.id]: inputValue === expectedValue
    }));
  };

  return (
    <div className="row">
      <table
        id="datatable-buttons"
        className="table table-bordered dt-responsive nowrap w-100 "
      >
        <thead>
          <tr>
            <th>
              <center>Product Name</center>
            </th>
            <th>
              <center>Sold Quantity</center>
            </th>
          </tr>
        </thead>
        {data?.map((item) => {
          return (
            <tr key={item.id}> {/* 必须添加唯一key,符合React列表渲染规范 */}
              <td>
                <h5 className="ps-5">{item.pName}</h5>
              </td>
              <td>
                <input
                  type="number"
                  className="form-control"
                  placeholder="XXX"
                  onChange={(e) => handleInputChange(e, item)}
                />
                {/* 根据当前行的状态显示提示 */}
                {matchStates[item.id] && <p>Value is Matching</p>}
              </td>
            </tr>
          );
        })}
      </table>
    </div>
  );
}

export default DailyStock;

方式二:拆分为独立子组件

把每行的逻辑封装成单独的子组件,子组件自身维护校验状态,代码结构更清晰:

import React from "react";
import { useState, useEffect } from "react";
import axios from "axios";

// 子组件:单独处理每行的输入与校验逻辑
const StockRow = ({ item }) => {
  const [isMatching, setIsMatching] = useState(false);

  const handleInputChange = (e) => {
    const inputValue = parseInt(e.target.value, 10);
    const expectedValue = item.pQty - item.saleStock;
    setIsMatching(inputValue === expectedValue);
  };

  return (
    <tr key={item.id}>
      <td>
        <h5 className="ps-5">{item.pName}</h5>
      </td>
      <td>
        <input
          type="number"
          className="form-control"
          placeholder="XXX"
          onChange={handleInputChange}
        />
        {isMatching && <p>Value is Matching</p>}
      </td>
    </tr>
  );
};

function DailyStock() {
  const [data, setData] = useState([]);

  useEffect(() => {
    getDailyData();
  }, []);

  const getDailyData = () => {
    axios.get("http://localhost:4000/api/stocks/view-stock").then((res) => {
      const getData = res.data.data;
      setData(getData);
    });
  };

  return (
    <div className="row">
      <table
        id="datatable-buttons"
        className="table table-bordered dt-responsive nowrap w-100 "
      >
        <thead>
          <tr>
            <th>
              <center>Product Name</center>
            </th>
            <th>
              <center>Sold Quantity</center>
            </th>
          </tr>
        </thead>
        {data?.map((item) => (
          <StockRow key={item.id} item={item} />
        ))}
      </table>
    </div>
  );
}

export default DailyStock;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:50:27