具有以下数据结构:
const foo = [
{
a: 'xxx',
b: 'xxx',
c: {
e: 'xxx',
...
}
}
...
]
有可能用这个路径对象访问e
的值吗
const path = [0, 'c', 'e']
并对其进行编辑?
我试着做
setResponseState(prevState => {
let data = prevState.responseData
path.forEach(id => data = data[id])
data = {}
return prevState
})
path
是一个上下文值,但我发现data
是一个副本,因此没有保存在反应状态中
谢谢
如果您修改更新forEach
中的最后一个值,如下所示,应该可以编辑对象。基本上,这样可以避免覆盖对象引用,只更新值。
const foo = [
{
a: "xxx",
b: "xxx",
c: {
e: "xxx",
},
},
];
const path = [0, "c", "e"];
setResponseState((prevState) => {
let data = prevState.responseData;
path.forEach((id, i) =>
i === path.length - 1 ? (data[id] = {}) : (data = data[id])
);
return prevState;
});
检查此样本是否改变对象
const foo = [
{
a: "xxx",
b: "xxx",
c: {
e: "xxx",
},
},
];
const path = [0, "c", "e"];
let data = foo;
path.forEach((id, i) =>
i === path.length - 1 ? (data[id] = {}) : (data = data[id])
);
console.log(foo)
如果您只想访问值,那么您的现有代码基本上是好的,您只需要返回值。
const foo = [
{
a: 'xxx',
b: 'xxx',
c: {
e: 'xxx',
}
}
]
const path = [0, 'c', 'e']
function setResponseState(prevState) {
let data = foo; //prevState.responseData
path.forEach(id => data = data[id])
return data;
};
console.log(setResponseState());
这(通过提供的路径访问嵌套值)是非常有表现力的reduce
方法与可选链接协作的标准任务,以确保实现故障安全。。。
const foo = [{
a: "zzz",
b: "yyy",
c: {
e: "xxx",
},
}];
console.log({ foo });
console.log(
'[0, "c", "e"].reduce((value, key) => value?.[key], foo) ...',
[0, "c", "e"].reduce((value, key) => value?.[key], foo)
);
console.log(
'[0, "C", "e"].reduce((value, key) => value?.[key], foo) ...',
[0, "C", "e"].reduce((value, key) => value?.[key], foo)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
如果要改变对象的嵌套属性,最好在函数中使用上述方法。。。
const foo = [{
a: "zzz",
b: "yyy",
c: {
e: "xxx",
f: "uuu",
},
}];
function assignValueToExistingNestedProperty(type, path, value) {
const [lastKey, ...keyList] = path.reverse();
// access the next to last property value.
const reference = keyList
.reverse()
.reduce((value, key) => value?.[key], type);
Object.assign((reference ?? {}), { [lastKey]: value });
return type;
}
console.log({ foo });
console.log(
'assignValueToExistingNestedProperty(foo, [0, "c", "e"], "AAA") ...',
assignValueToExistingNestedProperty(foo, [0, "c", "e"], "AAA")
);
console.log(
'assignValueToExistingNestedProperty(foo, [0, "C", "e"], "BBB") ...',
assignValueToExistingNestedProperty(foo, [0, "C", "e"], "BBB")
);
console.log({ foo });
.as-console-wrapper { min-height: 100%!important; top: 0; }