Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/374.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.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 在React中设置状态期间克隆对象/阵列的正确方法_Javascript_Reactjs - Fatal编程技术网

Javascript 在React中设置状态期间克隆对象/阵列的正确方法

Javascript 在React中设置状态期间克隆对象/阵列的正确方法,javascript,reactjs,Javascript,Reactjs,我首先说: constructor() { super(); this.state = { lists: ['Dogs','Cats'], items: {Dogs: [{name: "Snoopy"}, {name: "Lola"}, {name: "Sprinkles"}], Cats: [{name: "Felidae"}, {name: "Garfiled"}, {name: "Cat in th

我首先说:

constructor() {
   super();
      this.state = {
         lists: ['Dogs','Cats'], 
         items: {Dogs: [{name: "Snoopy"}, {name: "Lola"}, {name: "Sprinkles"}], 
                 Cats: [{name: "Felidae"}, {name: "Garfiled"}, {name: "Cat in the Hat"}] }             
   };

}
然后我有我的addItem函数:

handleAddItem(s) {      

  var key = Object.keys(s)[0];
  var value = s[key];

  var allItems = {...this.state.items};

      allItems[key].push({name: value});    

      this.setState({items: allItems});
}
在其他地方,我将s定义为:

var s={};
   s[this.props.idName] = this.refs.id.value;
这是可行的,但我想知道这是否是将元素添加到项中的一个键中的正确方法。AllItems确实指向了这个.state.items,我认为它应该是一个深度副本,但我不知道如何做到这一点


似乎items是一个对象,它保存键/值对,其中值是一个数组。对吗?我可以去哪里学习如何操作这样的结构?

我个人依赖这种深度复制策略。
JSON.parse(JSON.stringify(object))
而不是
spread
操作符,因为它让我在处理嵌套对象或多维数组时陷入了奇怪的错误

spread
运算符不会执行深度复制,如果我的判断正确,将导致React中嵌套的对象发生状态突变

请运行代码以更好地了解两者之间发生的情况。假设这是使用
spread
运算符进行变异的状态变量

const obj={Dogs:[{name:“Snoopy”}、{name:“Lola”}、{name:“springs”})、Cats:[{{name:“Felidae”}、{name:“garfield”}、{name:“帽子里的猫”};
const newObj={…obj};
console.log(“扩散拷贝变异前”)
console.log(“newObj:+newObj.Dogs[0].name”)//史努比
console.log(“旧对象:+OBJ.Dogs[0].name”)//史努比
newObj.Dogs[0].name=“克隆史努比”;
console.log(“扩散拷贝变异后”)
console.log(“newObj:+newObj.Dogs[0].name);//克隆史努比
console.log(“旧对象:+OBJ.Dogs[0].name);//克隆史努比
//即使在使用“扩展”操作符后,克隆对象上的更改也会影响到旧对象。这通常发生在嵌套对象的情况下。
//我个人可靠的深拷贝
console.log(“**********深度拷贝*************”);
console.log(“深度复制变异前”)
deepCopyObj=JSON.parse(JSON.stringify(obj));
console.log(“newObj:+newObj.Dogs[0].name”)//克隆史努比
console.log(“旧对象:+OBJ.Dogs[0].name);//克隆史努比
log(“DEEP OBJ:+deepCopyObj.Dogs[0].name”)//克隆史努比
deepCopyObj.Dogs[0].name=“深度克隆史努比”;
console.log(“深度复制变异后”)
console.log(“newObj:+newObj.Dogs[0].name);//克隆史努比
console.log(“旧对象:+OBJ.Dogs[0].name);//克隆史努比

console.log(“DEEP OBJ:+deepCopyObj.Dogs[0].name);//深度克隆Snoopy
一个问题可能是
var allItems={…this.state.items}
将仅对
此.state.items
进行浅克隆。因此,当您将数据推入此数组时,它将在您调用
setState
之前更改现有数组

你可以用它来解决这个问题

import { List, fromJS, Map } from 'immutable';

constructor() {
   super();
      this.state = {
       lists: List(['Dogs','Cats']), 
       items: fromJS({
        Dogs: [
          { name: "Snoopy" },
          ...
        ],
        Cats: [
          { name: "Felidae" },
          ...
        ]
      })
   };
}
然后您的add函数将如下所示:

handleAddItem(s) {      
  var key = Object.keys(s)[0];
  var value = s[key];

  var allItems = this.state.items.set(key, Map({ name: value }));
  this.setState({ items: allItems });
}

只是一个想法

我想添加更多关于克隆阵列的信息。您可以调用,将0作为第一个参数:

const clone = myArray.slice(0);

上面的代码创建了原始阵列的克隆;请记住,如果数组中存在对象,则会保留引用;i、 e.上面的代码没有对数组内容进行“深度”克隆。

选择的答案是一个奇迹,是南都卡拉迪迪的巨大支柱,我在项目中更新的对象内部有嵌套数组的bug,我不理解“深度”或“嵌套”数组的概念,对象没有被复制到新对象

这是我对他的修复的看法,让它看起来更吸引我,效果也一样好

我利用
lodash
并找到了它们的
.cloneDeep()
函数来满足我的更新状态需求

我了解到,绘制出防止任何bug的更新数组是处理此类问题的最佳方法,但我正在使用嵌套数组克隆整个对象,这些嵌套数组在状态中变异旧对象的数组

这是我的答案


const state = {
    fields: {
        "caNyDcSDVb": {
            id: "caNyDcSDVb",
            name: "test1",
            type: "text",
            options: ["A", "B", "C"]
        }
    },
};

const FieldCopy = (id) => {
    const newCopiedField = _.cloneDeep(state.fields[id]);
    newCopiedField.id = nanoid(10);
    return {
        ...state,
        fields: {
            ...state.fields,
            newCopiedField[id]: newCopiedField
        }
    };
};

但我们似乎正在直接更改状态,因为allItems实际上指向this.state.items。这就是为什么您不直接执行
this.state={dogs:[],cats:[]}
。当我尝试你的map函数时,我得到构造函数map需要'new'这意味着什么?我从'immutable'中添加了
{map}