在 componentDidMount() 中制作独立副本



我是javascript和act(16.9.0(的新手,所以我希望这个问题不要太明显:

我知道我可以用"..."复制字典,例如:const dict_new = {...dict_old} 我使用此表达式来避免引用副本。问题是,当我在异步组件DidMount((中定义字典并复制它时,尽管定义正确,但该副本仍然是引用的副本。让我展示我的代码:

async componentDidMount() {
try {
const res1 = await fetch('/postmongo/group/');
let grupos = await res1.json();
const res2 = await fetch('/postmongo/permiso/');
const permisos = await res2.json();
const dict_permisos = {};
permisos.forEach((perm) => {
dict_permisos[perm.descripcion] = {};
grupos.forEach((gr) => {
if (gr.Permisos_gemelo.some((p) => (p.nombre === perm.nombre))) {
dict_permisos[perm.descripcion][gr.name] = true;
} else {
dict_permisos[perm.descripcion][gr.name] = false;
}
});
});
const dict_permisos_inicial = {...dict_permisos}
this.setState({
grupos,
permisos,
dict_permisos,
dict_permisos_inicial,
});
console.log(this.state);
} catch (e) {
console.log(e);
}
}

dict_permisos_inicial是引用副本(即当dict_permisos更改时它正在更改(,并且它应该是独立的。我错过了什么?我通过定义字典两次来解决,也许我应该在组件DidMount((之外构建字典,但是,在哪里?

尝试 Object.assign

在大多数情况下,对象重置和展开的工作方式相同,关键区别在于展开定义属性,而 Object.assign(( 设置它们。这意味着 Object.assign(( 触发器 setter。

值得记住的是,除此之外,Object rest/spread 1:1映射到Object.assign((,并且与数组(可迭代(扩展的行为不同。例如,在展开数组时,将展开空值。但是,使用对象展开时,空值将以静默方式展开为空。

数组(可迭代(扩展示例

const x = [1, 2, null , 3];
const y = [...x, 4, 5];
const z = null;
console.log(y); // [1, 2, null, 3, 4, 5];
console.log([...z]); // TypeError

对象展开示例

const x = null;
const y = {a: 1, b: 2};
const z = {...x, ...y};
console.log(z); //{a: 1, b: 2}

谢谢大家,我在这个博客中找到了解决方案:https://medium.com/javascript-in-plain-english/how-to-deep-copy-objects-and-arrays-in-javascript-7c911359b089

转录他的话:"对于包含其他对象或数组的对象和数组,复制这些对象需要深度复制。 否则,对嵌套引用所做的更改将更改嵌套在原始对象或数组中的数据。

基本上,常量 dict_permisos_inicial = {...dict_permisos} 我正在执行一个浅拷贝,并且在使用简单的字典时工作得很好。但是,我的字典是嵌套的,浅层标准副本不起作用。例如:

> dict = {
...   permiso1: { grupo1: true, grupo2: false },
...   permiso2: { grupo1: false, grupo2: true }
... }
{
permiso1: { grupo1: true, grupo2: false },
permiso2: { grupo1: false, grupo2: true }
}
> dict_copy = {...dict}
{
permiso1: { grupo1: true, grupo2: false },
permiso2: { grupo1: false, grupo2: true }
}
> dict_copy["permiso1"]["grupo1"]=false
false
> dict_copy
{
permiso1: { grupo1: false, grupo2: false },
permiso2: { grupo1: false, grupo2: true }
}
> dict
{
permiso1: { grupo1: false, grupo2: false },
permiso2: { grupo1: false, grupo2: true }
}

从他展示的解决方案中,我使用了"ramda"。在反应中:

import { clone } from 'ramda'
[some code]
const dict_permisos_inicial = clone(dict_permisos);

在节点中:

> var R = require("ramda")
undefined
> dict_copy = R.clone(dict)
{
permiso1: { grupo1: true, grupo2: false },
permiso2: { grupo1: false, grupo2: true }
}
> dict_copy["permiso1"]["grupo1"]=false
false
> dict_copy
{
permiso1: { grupo1: false, grupo2: false },
permiso2: { grupo1: false, grupo2: true }
}
> dict
{
permiso1: { grupo1: true, grupo2: false },
permiso2: { grupo1: false, grupo2: true }
}

最新更新