更改所提供 ID 的对象数组的值
我如何更改所提供 ID 的值?我一直收到此 TypeError:无法设置未定义的属性(设置“select”)
const data = [
{
id: 1,
select: false
},
{
id: 2,
select: true
},
{
id: 3,
select: true
},
{
id: 4,
select: false
},
{
id: 5,
select: false
}
];
const ids = [1, 2, 4];
let d = [...data];
for (let i = 0; i < d.length - 1; i++) {
const objIndex: number = d?.findIndex((obj: any) => obj.id === ids[i]);
d[objIndex].select = true;
console.log(d);
}
我想更改所提供 ID 的布尔值并创建一个新的数据对象(相同数据但更改了所提供 ID 的布尔值)需要帮助!
也许不是在数据中搜索特定的 ID,而是在 ID 列表中搜索,这使其更简单,并且根据数据的大小和 ID 的数量,它可能会更快:
const data = [
{
id: 1,
select: false
},
{
id: 2,
select: true
},
{
id: 3,
select: true
},
{
id: 4,
select: false
},
{
id: 5,
select: false
}
];
const ids = [1, 2, 4];
for (let i = 0; i < data.length; i++) {
if (ids.includes(data[i].id))
data[i].select = true;
}
console.log(data);
您正在迭代
d
数组,并尝试使用未指向此数组中任何值的索引访问
ids
数组。因此
.findIndex
返回
-1
,当您尝试在
d[objIndex]
中访问它时,它在那里也是未定义的,因为没有具有该索引的元素。
为了修复您的代码,您必须先迭代
ids
数组以获取具有精确 ID 的对象的索引,然后使用该索引更改值。
已修复代码:
const data = [
{
id: 1,
select: false
},
{
id: 2,
select: true
},
{
id: 3,
select: true
},
{
id: 4,
select: false
},
{
id: 5,
select: false
}
];
const ids = [1, 2, 4];
let d = [...data];
ids.forEach((id) => {
const objIndex: number = d?.findIndex((obj: any) => obj.id === id);
// safe guard if there is no object with that id
if (objIndex === -1) {
return;
}
d[objIndex].select = true;
})
您当前的
for
循环正在执行
d.length-1
次迭代,因此
i
将超出
ids
中索引的有效索引范围。因此,当您尝试对不是
ids
中索引的
i
值执行
ids[i]
时,您会返回
undefined
,这最终导致
.findIndex()
无法找到对象,因为没有具有
undefined
id 属性的对象。这会导致下一行代码崩溃,因为它试图更新数组中不存在的对象。为了使您的代码正常工作,您的条件应该是
i < ids.length;
。
但是,假设
data
是一个状态值(我在这里收集了它,因为您将其标记为
reactjs
并且您已经克隆了数据数组),您不应该像现在这样在
data
中修改对象。主要问题是
const d = [...data]
仅对数组进行浅表复制,因此对象仍然是引用,这意味着在执行
d[objIndex].select = true
时直接修改状态,这可能会导致重新渲染问题。
要解决这个问题,您可以对数组进行深度克隆,或者对数据使用
.map()
并返回一个新对象(如果需要更新),如下所示。下面的代码使用
spread 语法
(
...
) 来创建一个具有当前对象所有属性的新对象(如果其 id
在
ids
中),然后我们覆盖
select
的值以将其更新为
true
:
const data = [{ id: 1, select: false }, { id: 2, select: false }, { id: 3, select: false }, { id: 4, select: false }, { id: 5, select: false } ];
const ids = [1, 2, 4];
let newData = data.map(obj => ids.includes(obj.id) ? {...obj, select: true} : obj);
console.log(newData);