反应数组状态不推送值

时间:2021-05-24 06:47:35

标签: reactjs react-hooks

我想用新值更新我的状态数组。基本上,我想向数组添加一些新值。但不能这样做

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"] 我只想存储数组的第二个值

4 个答案:

答案 0 :(得分:2)

问题

  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并返回这个值用于映射。

编辑

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

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

演示

Edit react-array-state-not-pushing-value

答案 1 :(得分:1)

const newArr = ['data3','data4','data5'];

setValues((prev)=>([...prev, ...newArr]));

你可以这样做

更新

const newData = [["data 43", "data 1.1"],["data 65", "data 2.2"] ]
setValues((prev)=>([...prev, ...newData.flat()]));

答案 2 :(得分:0)

如果所有嵌套数组的长度相等,您可以使用这样的方法进行迭代

newData = [["data 1", "data 1.1"],["data 2", "data 2.2"]]
const rowLength = newData[0].length
const returnArr = []
for(let i=0; i<rowLength; i++){
  returnArr.push(newData.map(row => row[i]))
}
console.log(returnArr.flat())

答案 3 :(得分:0)

setData 来自您的 useState 并且有点异步。你不能在循环中使用它。您要做的是准备您的最终数据对象,并仅使用它调用 setData 一次。

// No change here
const [values, setValues] = useState(["data1", "data2"]);
const newData = [["data 1", "data 1.1"],["data 2", "data 2.2"] ]

// Flatten the array
const finalData = newData.flat();

// Update the state only once
setValues(finalData);