首页 > 解决方案 > 反应数组状态不推送值

问题描述

我想用新值更新我的状态数组。基本上,我想向数组添加一些新值。但无法做到这一点

const [values, setValues] = useState(["data1", "data2"]);

const newData = [["data 43", "data 1.1"],["data 65", "data 2.2"] ]

newData.map((item) => {
  setValues([...values, item[1]]);
});
 
returns ["data1", "data2", "data2.2"]

我想要的是["data1", "data2", "data 1.1", "data 2.2"] 我只想存储数组的第二个值

标签: reactjsreact-hooks

解决方案


问题

  1. 使用Array.prototype.map是将现有数组映射到新数组,而不是用于发布副作用,例如更新 React 状态或推送到其他数组。
  2. 在循环中对状态更新进行排队时,您必须使用功能状态更新来正确更新前一个状态,而不是前一个渲染周期中的状态。

解决方案

const [values, setValues] = useState(["data1", "data2"]);

...

["data3", "data4", "data5"].forEach((item) => {
  setValues(values => [...values, item]);
});

由于您实际上只是将一个数组附加到另​​一个数组,因此您可以通过删除循环来简化此操作。(好吧,您仍在循环,但现在循环在状态更新器函数内,因此您避免了状态循环问题

setValues(values => [...values, ...["data3", "data4", "data5"]]);

或者

setValues(values => values.concat(["data3", "data4", "data5"]));

更新

使用功能状态更新来浅拷贝前一个values并将新数据映射到包含第二个元素的数组并浅拷贝新结果。

const newData = [
  ["data 1", "data 1.1"],
  ["data 2", "data 2.2"]
];

...

const [values, setValues] = useState(["data 1", "data 2"]);

...

setValues((values) => [
  ...values,
  ...newData.map(([, newValue]) => newValue) // *
]);

*newData是一个数组数组,[, newValue]在回调中使用解构赋值“跳过”第 0 个元素并将第 1 个元素分配给一个变量newValue并返回此值以进行映射。

编辑

要删除在新数据中创建的重复项,请使用 aSet删除它们:

setValues((values) => [
  ...new Set([...values, ...newData.map(([, newValue]) => newValue)])
]);

演示

编辑 react-array-state-not-pushing-value


推荐阅读