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

React Hooks中如何正确向嵌套数组添加元素?当前写法生成错误结构

React Hooks嵌套数组添加元素错误修复

问题场景

原本的state是一个包含对象的数组,对象内有ages数组,点击按钮想向ages中添加随机生成的age值,但操作后state结构完全错误:

原state定义:

const [state, setState] = useState([
  {
    name: "test",
    lname: "lname",
    ages: [
      {
        age: 30
      }
    ]
  }
]);

错误的点击事件代码:

const randomAge = () => {
  let rg = ((Math.random() * 1000) / 10).toFixed();
  setState({ ...state, ages: { ...state.ages, age: rg } });
};

错误输出:

{
  "0": {
    "name": "test",
    "lname": "lname",
    "ages": [
      {
        "age": 30
      }
    ]
  },
  "ages": {
    "rg": "34"
  }
}

期望输出:

[
  {
    "name": "test",
    "lname": "lname",
    "ages": [
      {
        "age": 30
      },
      {
        "age": 50
      },
      {
        "age": 60
      }
    ]
  }
]

错误原因

  1. 原state是数组类型,但setState({ ...state })把数组展开成了对象(索引作为键),直接改变了state的整体结构。
  2. 错误地给state根节点添加ages属性,而不是更新数组中第一个对象的ages数组;且把ages当成对象处理,用对象展开语法,而ages本质是数组,应该用数组展开来添加元素。

正确代码

使用函数式更新确保拿到最新state,同时保持数组结构,正确更新嵌套的ages数组:

const randomAge = () => {
  let rg = ((Math.random() * 1000) / 10).toFixed();
  setState(prevState => {
    // 遍历原数组(这里只有一个元素),复制对象并更新ages
    return prevState.map(item => ({
      ...item,
      ages: [...item.ages, { age: Number(rg) }] // 转成数字保持类型一致
    }));
  });
};

如果确定数组中只有一个元素,也可以简化写法:

const randomAge = () => {
  let rg = ((Math.random() * 1000) / 10).toFixed();
  setState(prevState => [
    {
      ...prevState[0],
      ages: [...prevState[0].ages, { age: Number(rg) }]
    }
  ]);
};

关键说明

  • 函数式更新setState(prevState => ...):避免闭包导致的state过期问题,确保基于最新状态修改。
  • 保持state结构:始终返回数组,和初始state的结构一致。
  • 数组更新:用[...原数组, 新元素]的方式创建新数组,符合React不可变更新的原则,避免直接修改原state。
  • 类型统一:toFixed()返回字符串,转成Number后和原age的数字类型匹配。

内容的提问来源于stack exchange,提问作者vivek singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:30:51