React 18中使用useState更新对象数组状态失效问题求助
嘿,看了你的代码,发现你踩了几个关键的小坑,咱们一个个理清楚解决掉:
1. 输入框的状态绑定完全错了!
你现在给input的onChange绑定了setNames,这会直接把原本是数组类型的names状态改成输入框的字符串内容,彻底破坏了状态结构——后面再想往数组里加元素自然就失效了。应该把它改成setName,把输入的内容存在专门的name状态里:
<input type="text" value={name} placeholder="add names" onChange={(e) => setName(e.target.value)} />
2. 状态更新要考虑异步特性(优化点)
React的setState是异步执行的,如果你直接依赖当前的names变量来更新状态,偶尔会拿不到最新的值。推荐用函数式更新的方式,确保获取到最新的前序状态:
function addNames(e) { e.preventDefault(); // 加个判断,避免空输入 if (!name.trim()) return; setNames(prevNames => [...prevNames, { id: prevNames.length, name }]); // 别忘了清空输入框,提升体验 setName(""); }
3. 列表渲染的写法搞反了
你注释掉的数组map写法其实是正确的,后来改成的Object.keys(names).map完全没必要(因为names是数组,不是对象),而且当前的渲染代码还有语法错误:key={names}是无效的,names[item]也不对。直接还原正确的数组遍历写法就行:
<ul> {names.map((item) => ( <li key={item.id}>{item.name}</li> ))} </ul>
修正后的完整代码
把这些问题都修复后,完整的组件代码应该是这样的:
import React, { useState } from "react"; import './App.css'; function App() { const [name, setName] = useState(""); const [names, setNames] = useState([]); function addNames(e) { e.preventDefault(); if (!name.trim()) return; setNames(prevNames => [...prevNames, { id: prevNames.length, name }]); setName(""); } return ( <div className="App"> <form onSubmit={addNames}> <input type="text" value={name} placeholder="add names" onChange={(e) => setName(e.target.value)} /> <button>Submit</button> </form> <ul> {names.map((item) => ( <li key={item.id}>{item.name}</li> ))} </ul> </div> ); } export default App;
内容的提问来源于stack exchange,提问作者kubaSpolsky
相关产品推荐
相关产品推荐

