如何在 React 中通过按钮点击动态添加列表项(li)

8次阅读

如何在 React 中通过按钮点击动态添加列表项(li)

本文详解如何使用 react 的 useState Hook 管理动态列表状态,实现点击按钮后将两个输入框的值组合并渲染为 元素,插入到 中,涵盖状态设计、事件处理、列表渲染及关键注意事项。

本文详解如何使用 react 的 usestate hook 管理动态列表状态,实现点击按钮后将两个输入框的值组合并渲染为 `

  • ` 元素,插入到 `
      ` 中,涵盖状态设计、事件处理、列表渲染及关键注意事项。

      在 React 应用中,动态生成 dom 元素(如

    • )不能通过原生 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 响应式开发的基石
  • text=ZqhQzanResources