如何在提交新数据时为React Table动态新增数据展示行
实现方案
核心逻辑是把当前单条数据存储的结构改为数组存储所有提交的条目,再遍历数组渲染表格行即可,具体修改如下:
第一步:修改App组件
你当前把四个字段分开存为单独的state,每次提交都会覆盖旧值,所以只能展示一行。我们把存储结构改成对象数组,每提交一次就往数组里追加一条新数据:
import { useState, useRef } from 'react' import Container from 'react-bootstrap/Container' import Button from 'react-bootstrap/Button' import Banner from './Banner' // 按照你自己的实际文件路径调整 import Table from './Table' function App() { // 用单个数组存储所有提交的商品条目,每个条目是包含四个字段的对象 const [items, setItems] = useState([]) const itemNameRef = useRef() const itemCostRef = useRef() const itemSellRef = useRef() // 利润可直接通过成本和售价计算,不需要单独的ref和输入框 function handleSubmit(e) { // 先获取输入值并做基础格式处理 const name = itemNameRef.current.value.trim() const cost = Number(itemCostRef.current.value.trim()) const sell = Number(itemSellRef.current.value.trim()) // 非空/合法性校验可根据自己的需求扩展 if (!name || isNaN(cost) || isNaN(sell)) return const profit = sell - cost // 不可变更新state:把新条目追加到数组末尾 setItems(prevItems => [...prevItems, { name, cost, sell, profit }]) // 提交后清空输入框方便下次输入 itemNameRef.current.value = '' itemCostRef.current.value = '' itemSellRef.current.value = '' } return ( <Container> <Banner /> <br></br> <Container> <table className="table"> <thead> <tr> <th scope="col">Item</th> <th scope="col">Cost</th> <th scope="col">Sell</th> <th scope="col">Profit</th> </tr> </thead> <tbody> <tr> <td> <input ref={itemNameRef} /> </td> <td> <input ref={itemCostRef} type="number" min="0" step="0.01" /> </td> <td> <input ref={itemSellRef} type="number" min="0" step="0.01" /> </td> <td> {/* 利润不需要用户输入,可改为实时计算展示 */} <span>{(itemSellRef.current?.value && itemCostRef.current?.value) ? (Number(itemSellRef.current.value) - Number(itemCostRef.current.value)).toFixed(2) : ''}</span> </td> </tr> </tbody> </table> </Container> <Button onClick={handleSubmit} >Submit</Button> {/* 把所有条目传给Table组件 */} <Table items={items}/> </Container> ); } export default App;
第二步:修改Table组件
接收存储所有条目的数组,遍历数组渲染每一行即可:
import React from "react"; // 接收items数组作为props export default function Table({ items }) { return ( <div> <table className="table"> <thead> <tr> <th scope="col">Item Name</th> <th scope="col">Cost</th> <th scope="col">Sell</th> <th scope="col">Profit</th> </tr> </thead> <tbody> {/* 遍历数组渲染每一行,加key避免React控制台警告 */} {items.map((item, index) => ( <tr key={index}> <td>{item.name}</td> <td>$ {item.cost.toFixed(2)}</td> <td>$ {item.sell.toFixed(2)}</td> <td>$ {item.profit.toFixed(2)}</td> </tr> ))} {/* 数组为空时展示空状态提示,可根据需求调整 */} {items.length === 0 && ( <tr> <td colSpan={4} className="text-center">暂无数据</td> </tr> )} </tbody> </table> </div> ); }
额外优化点
- 给金额输入框加
type="number"限制只能输入数字,加step属性支持小数输入,避免非法格式提交 - 用
toFixed(2)保留两位小数,符合金额类场景的展示习惯 - 可以根据需要扩展校验规则,比如售价不能低于成本之类的逻辑
内容的提问来源于stack exchange,提问作者Austin Poythress
相关产品推荐
相关产品推荐

