You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 23:07:34