
本文详解如何使用 React 的 useState Hook 实现点击按钮后,将两个输入框的值组合并动态渲染为 列表项,强调状态管理、列表渲染与 key 的正确使用。
本文详解如何使用 react 的 usestate hook 实现点击按钮后,将两个输入框的值组合并动态渲染为 `
在 React 应用中,动态向列表(如
- )中添加
- 元素,本质是响应式地更新 UI 状态,而非直接操作 DOM。核心在于:用状态(useState)存储待渲染的数据,再通过 map() 将数据映射为 JSX 元素,并确保每个元素拥有稳定唯一的 key。
以下是一个完整、可运行的实现方案:
✅ 正确做法:用数组状态管理列表项
首先,声明一个用于存储所有待显示条目的数组状态:
const [values, setValues] = useState([]);
该数组每一项代表一个
- 的文本内容(例如 "Groceries 45")。当用户点击“Add Expense”按钮时,我们应将当前两个输入框的值拼接后追加到该数组中:
function handleClick() { const newItem = `${firtValue.trim()} ${secValue.trim()}`; if (newItem.trim()) { // 防止空条目 setValues(prev => [...prev, newItem]); } }⚠️ 注意:使用函数式更新 setValues(prev => [...prev, newItem]) 更安全,避免闭包导致的状态陈旧问题;同时添加空值校验,提升用户体验。
接着,在 JSX 中渲染列表时,不要调用函数(如 {listOfLi()}),而应直接渲染已计算好的 JSX 数组:
const listOfLi = values.map((value, index) => ( <li key={index}>{value}</li> )); // 在返回 JSX 中: <ul>{listOfLi}</ul>✅ 关键点:key 必须存在且唯一。此处使用 index 可行(因条目仅追加、不重排/删除),但若后续需支持编辑或删除,建议改用唯一 ID(如 crypto.randomUUID() 或时间戳+索引组合)。
? 修复原代码中的典型错误
- ❌ listOfLi() 是一个函数,但被直接写成 {listOfLi}(未调用)→ 渲染的是函数对象,非 JSX;
- ❌ handleClick 中仅调用 listOfLi(),未触发状态更新 → UI 不会重新渲染;
- ❌ 输入状态更新逻辑混乱(如 hadnleChane / hadnleChan 拼写错误、职责错位)→ 已统一修正为语义清晰的 setFirtValue / setSecValue。
? 完整优化后的关键片段(精简版)
// 状态声明 const [firtValue, setFirtValue] = useState(""); const [secValue, setSecValue] = useState(""); const [values, setValues] = useState([]); // 输入处理(修正命名与逻辑) const handleItemChange = (e) => setFirtValue(e.target.value); const handleAmountChange = (e) => setSecValue(e.target.value); // 添加条目 const handleClick = () => { const text = `${firtValue.trim()} ${secValue.trim()}`; if (text.trim()) { setValues(prev => [...prev, text]); // 可选:清空输入框 setFirtValue(""); setSecValue(""); } }; // 列表渲染 const listItems = values.map((item, i) => ( <li key={i}>{item}</li> ));在 JSX 中使用:
<div className="add-item">Item <input type="text" onChange={handleItemChange} placeholder="Add Item" /> </div> <div className="add-item">Amount <input type="number" onChange={handleAmountChange} placeholder="Add Amount" /> </div> <button onClick={handleClick}>Add Expense</button> <ul>{listItems}</ul>? 总结与最佳实践
- ✅ 状态即数据源:所有动态内容必须由 React 状态驱动;
- ✅ 列表渲染必带 key:即使使用索引,也要确保其在列表生命周期内稳定;
- ✅ 避免副作用式 DOM 操作:不使用 document.createElement 或 innerHTML;
- ✅ 输入后及时清理(可选):提升交互流畅性;
- ✅ 添加基础校验:防止空字符串、NaN 等无效数据进入列表。
掌握这一模式,你不仅能实现
- 动态添加,还能轻松扩展为 Todo 列表、购物车、日志面板等常见功能模块。









