React.js表格行内输入值与数据库值逐行匹配验证问题
解决方案
问题根源
你之前的写法存在两个核心问题:
onChange事件函数里直接返回JSX不会被React渲染到DOM中,事件回调的返回值无法触发视图更新- 全局状态会让所有行的校验结果绑定在一起,无法实现逐行独立控制
下面提供两种可行的实现方式:
方式一:用对象存储逐行状态
通过对象存储每行的匹配状态,以数据的唯一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
相关产品推荐
相关产品推荐

