如何将React开支追踪列表拆分为分组展示项?
解决开支分组显示问题
核心问题是你把开支的名称和金额拆分到两个独立数组中存储,渲染时分别遍历自然会导致所有名称、所有金额各自扎堆,无法一一对应分组。正确的思路是将每一项开支的完整信息(名称+金额)作为单个对象存储在同一个数组里,这样就能轻松实现每组展示一项开支的需求。
具体修改步骤:
- 重构状态管理:合并两个数组状态为一个
expenses数组,每个元素包含单条开支的完整信息;保留输入框的单个值状态用于收集用户输入。 - 修改表单提交逻辑:提交时将名称和金额打包成一个对象添加到
expenses数组,无需再维护两个分离的数组。 - 调整渲染逻辑:遍历
expenses数组,每个元素渲染为一组开支项。
修改后的完整代码:
import "./App.css"; import { useState } from "react"; export default function App() { // 单个输入框的临时状态 const [expenseName, setExpenseName] = useState(""); const [expenseCost, setExpenseCost] = useState(0); // 存储所有开支的数组,每个元素是完整的开支对象 const [expenses, setExpenses] = useState([]); function handleFormSubmit(e) { e.preventDefault(); // 打包成单个开支对象,用时间戳生成唯一id(比数组长度更可靠) const newExpense = { id: Date.now(), name: expenseName.trim(), cost: Number(expenseCost) // 确保金额是数字类型 }; // 更新开支数组 setExpenses([...expenses, newExpense]); // 提交后清空输入框 setExpenseName(""); setExpenseCost(0); } function handleInputChangeName(e) { setExpenseName(e.target.value); } function handleInputChangeCost(e) { setExpenseCost(e.target.value); } return ( <div className="App"> <div id="title"> <h1>Expense tracker</h1> </div> <div id="createExpense"> <form onSubmit={handleFormSubmit}> <input required placeholder="Enter expense name..." type="text" name="expenseName" value={expenseName} onChange={handleInputChangeName} /> <input required placeholder="Enter expense cost..." type="number" name="expenseCost" value={expenseCost} onChange={handleInputChangeCost} /> <button>Save</button> </form> </div> <div id="expenseList"> <ul> {/* 遍历完整开支数组,每个元素渲染为一组 */} {expenses.map((expense) => ( <li key={expense.id} className="expense-item"> <span className="expense-name">{expense.name}</span> <span className="expense-cost">${expense.cost.toFixed(2)}</span> </li> ))} </ul> </div> </div> ); }
额外优化提示:
- 用
Date.now()生成id比依赖数组长度更可靠,避免删除开支后数组长度变化导致id重复的问题。 - 提交后清空输入框提升用户体验。
- 可以给每组开支项添加CSS类(比如
expense-item),方便样式上区分分组,比如添加边框、间距等。
内容的提问来源于stack exchange,提问作者Dark Galaxy
相关产品推荐
相关产品推荐

