在componentDidMount()内部制作独立副本

问题描述 投票:0回答:2

我对javascript并不陌生,并且会做出反应(16.9.0),所以我希望这个问题不太明显:

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

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更改时,它正在更改),它应该是独立的。我想念什么?我通过两次定义字典来解决,也许我应该在componentDidMount()之外构建字典,但是,在哪里?

javascript reactjs dictionary react-lifecycle
2个回答
0
投票

尝试Object.assign

大多数情况下,对象重置和散布都以相同的方式进行,主要区别在于散布定义属性,而Object.assign()设置属性。这意味着Object.assign()触发设置器。

值得记住的是,除此之外,对象休息/扩展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}

0
投票

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

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

基本上,使用const 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”。在React中:

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 }
}
© www.soinside.com 2019 - 2024. All rights reserved.