Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在componentDidMount()内制作独立副本_Javascript_Reactjs_Dictionary_React Lifecycle - Fatal编程技术网

Javascript 在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

我不熟悉javascript和react(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_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},因为我猜它们是等价的。