Javascript 在componentDidMount()内制作独立副本
我不熟悉javascript和react(16.9.0),所以我希望这个问题不要太明显: 我知道我可以用“…”复制一本字典,例如:const dict_new={…dict_old} 我使用此表达式是为了避免引用副本。问题是,当我在异步componentDidMount()中定义一个字典并复制它时,尽管定义正确,但该副本仍然是一个引用的字典。让我展示一下我的代码:Javascript 在componentDidMount()内制作独立副本,javascript,reactjs,dictionary,react-lifecycle,Javascript,Reactjs,Dictionary,React Lifecycle,我不熟悉javascript和react(16.9.0),所以我希望这个问题不要太明显: 我知道我可以用“…”复制一本字典,例如:const dict_new={…dict_old} 我使用此表达式是为了避免引用副本。问题是,当我在异步componentDidMount()中定义一个字典并复制它时,尽管定义正确,但该副本仍然是一个引用的字典。让我展示一下我的代码: async componentDidMount() { try { const res1 = await
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_inical是引用副本(即,当dict_permisos更改时,它正在更改),它应该是独立的。我错过了什么?我通过两次定义字典解决了这个问题,也许我应该在componentDidMount()之外构建字典,但是,在哪里?尝试Object.assign
对于大多数情况,对象重置和排列的工作方式相同,关键区别在于排列定义属性,而object.assign()设置属性。这意味着Object.assign()会触发setter
值得记住的是,除此之外,对象rest/spread 1:1映射到object.assign(),并且与数组(iterable)spread的行为不同。例如,当扩展数组时,将扩展空值。但是,使用对象扩展空值会自动扩展为零
数组(Iterable)扩展示例
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}
对象扩展示例
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}
谢谢大家,我在这个博客中找到了解决方案: 转述他的话:“对于包含其他对象或数组的对象和数组,复制这些对象需要深度复制。否则,对嵌套引用所做的更改将更改嵌套在原始对象或数组中的数据。”
基本上,使用const dict_permisos_inical={…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 }
}
从他展示的解决方案来看,我使用了“拉姆达”。在反应中:
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 }
}
您可以使用Object.assign为您执行此操作:const dict_permisos_inical=Object.assign({},dict_permisos)应该可以解决问题谢谢!但我担心它不起作用,我写const dict_permisos_inical=Object.assign({},dict_permisos),当使用Webpack编译时,React或Webpack会自动更改为const dict_permisos_inical={…dict_permisos},因为我猜它们是等价的。