
本文详解如何使用 React 的 useState Hook 管理动态列表状态,实现点击按钮后将两个输入框的值组合并渲染为 元素,插入到 中,涵盖状态设计、事件处理、列表渲染及关键注意事项。
本文详解如何使用 react 的 usestate hook 管理动态列表状态,实现点击按钮后将两个输入框的值组合并渲染为 `
- ` 中,涵盖状态设计、事件处理、列表渲染及关键注意事项。
- )不能通过原生 DOM 操作(如 document.createElement)实现,而应遵循“状态驱动视图”的核心原则:将待渲染的数据存入 state,再在 JSX 中通过 .map() 渲染为元素列表。
✅ 正确做法:用数组状态管理列表项
首先,声明一个用于存储所有待显示条目的数组状态:
const [values, setValues] = useState([]);
该数组每一项代表一个
- 的文本内容(例如 "Groceries 85")。当用户点击“Add Expense”按钮时,我们应将当前两个输入框的值拼接后追加进该数组:
function handleClick() { // 拼接 Item 和 Amount,避免空值导致冗余空格 const newItem = `${firtValue.trim()} ${secValue.trim()}`.trim(); if (newItem) { setValues(prev => [...prev, newItem]); // 推荐使用函数式更新 } }⚠️ 注意:使用 setValues(prev => [...prev, newItem]) 而非 setValues(values.concat(...)),既符合 React 最佳实践(避免闭包陷阱),也更语义清晰。
接着,在 JSX 中直接渲染该数组:
<ul> {values.map((item, index) => ( <li key={index}>{item}</li> ))} </ul>⚠️ key 属性不可省略:React 要求列表渲染时每个元素必须有唯一、稳定、可预测的 key。此处使用 index 可行(因列表仅追加、不重排/删除),但若后续需支持编辑或删除,建议改用唯一 ID(如 Date.now() 或 uuid)。
? 修复原始代码的关键问题
- ❌ listOfLi() 是一个函数调用,但未返回 JSX 数组,且未被正确调用;
- ❌ handleClick 中仅调用 listOfLi(),但未触发重新渲染——React 中只有 state 或 props 变化才会触发 re-render;
- ❌ 输入状态名存在拼写错误(firtValue → 建议改为 firstValue 提升可维护性);
- ❌ onChange 事件处理器命名不一致(hadnleChane / hadnleChan),易引发维护风险。
✅ 完整优化版核心逻辑(含健壮性增强)
// 状态声明(修正拼写 + 新增 values) const [firstValue, setFirstValue] = useState(""); const [secondValue, setSecondValue] = useState(""); const [values, setValues] = useState([]); // 输入处理(精简统一) const handleFirstChange = (e) => setFirstValue(e.target.value); const handleSecondChange = (e) => setSecondValue(e.target.value); // 添加条目(带空值校验与函数式更新) const handleClick = () => { const combined = `${firstValue.trim()} ${secondValue.trim()}`.trim(); if (combined) { setValues(prev => [...prev, combined]); // 可选:清空输入框 setFirstValue(""); setSecondValue(""); } }; // 列表渲染(安全 + key 合规) const listItems = values.map((text, i) => ( <li key={`item-${i}`}>{text}</li> ));最后,在 JSX 中使用:
<div className="add-item"> Item <input type="text" value={firstValue} onChange={handleFirstChange} placeholder="Add Item" /> </div> <div className="add-item"> Amount <input type="number" value={secondValue} onChange={handleSecondChange} placeholder="Add Amount" /> </div> <button type="button" onClick={handleClick}>Add Expense</button> <ul>{listItems}</ul>? 提示:为提升用户体验,建议为输入框添加 value 属性(受控组件),并点击后清空输入框;同时对 type="number" 的输入做防 NaN 处理(如 parseFloat(secondValue) || 0),避免显示 "Item NaN"。
掌握这一模式,你不仅能动态添加
- ,还可轻松扩展为 Todo 列表、购物车、日志面板等任意动态列表场景——状态即数据,数据即视图,这是 React 响应式开发的基石。
在 React 应用中,动态生成 DOM 元素(如









