Javascript 修改&;在React中复制文件对象

Javascript 修改&;在React中复制文件对象,javascript,arrays,reactjs,Javascript,Arrays,Reactjs,我在React中有一个组件,我在其中传递一个file对象。我使用这个文件对象执行各种操作,但我也通过执行this.props.File.color=#000 在我的组件中,有一个函数可以触发父函数来复制文件对象 duplicate(i, a) { let dupeArr = a; const arr = [...this.state.files]; const index = i + 1; let name = dupeArr.name.slice(0, -

我在React中有一个组件,我在其中传递一个file对象。我使用这个文件对象执行各种操作,但我也通过执行
this.props.File.color=#000

在我的组件中,有一个函数可以触发父函数来复制文件对象

  duplicate(i, a) {
    let dupeArr = a;
    const arr = [...this.state.files];

    const index = i + 1;
    let name = dupeArr.name.slice(0, -4);
    Object.defineProperty(dupeArr, 'name', { writeable: true, value: `${name}-${a.color}.png`})

    arr.splice(index, 0, a);
    console.log(arr)
    // 2x File Objects
    // Original file
    // -- #cb0000 (Correct)
    // -- filename-#cb0000.png (Incorrect, why is it changing this name?)
    //Duplicated file
    // -- -- #cb0000 (Correct)
    // -- filename-#cb0000.png (Correct)
    this.setState({
      files: arr
    })
  }
组件

duplicate =()=> {
    this.props.file.color = this.getColor();
    console.log(this.props.file)
    //File Object
    // -- color: #cb0000
    // -- name:filename.png
    this.props.duplicate(this.props.file);
}
如您所见,它向文件对象添加了一个颜色值,并且文件名是正确的。然后,我将这些数据传递回父级中的复制函数

家长

duplicate =()=> {
    this.props.file.color = this.getColor();
    console.log(this.props.file)
    //File Object
    // -- color: #cb0000
    // -- name:filename.png
    this.props.duplicate(this.props.file);
}
i是数组索引,a是文件对象

  duplicate(i, a) {
    let dupeArr = a;
    const arr = [...this.state.files];

    const index = i + 1;
    let name = dupeArr.name.slice(0, -4);
    Object.defineProperty(dupeArr, 'name', { writeable: true, value: `${name}-${a.color}.png`})

    arr.splice(index, 0, a);
    console.log(arr)
    // 2x File Objects
    // Original file
    // -- #cb0000 (Correct)
    // -- filename-#cb0000.png (Incorrect, why is it changing this name?)
    //Duplicated file
    // -- -- #cb0000 (Correct)
    // -- filename-#cb0000.png (Correct)
    this.setState({
      files: arr
    })
  }
我在这里做的是获取传递给它的文件对象,定义该文件对象的名称,然后在将其设置为状态之前将其拼接到现有文件数组中

但是,由于某种原因,当我定义name属性时,它会同时更改数组中原始条目以及新文件对象中的名称


有什么建议吗?

原因是您正在修改原始文件对象,并且它仍在
此.state.files
中引用。您正在此处制作文件数组的副本:

const arr=[…this.state.files];
但这实际上不会生成数组中包含的文件对象的副本。它们仍在引用原始对象

您遇到了问题,因为您在这一行对文件对象进行变异,而复制的数组仍在引用原始对象:

Object.defineProperty(duperar,'name',{writeable:true,value:`${name}-${a.color}.png`})
假设您正在将文件对象转换为普通JS对象(如您在回答中提到的),然后只将要修改的对象的索引传递到
duplicate

duplicate=(索引)=>{
让filesCopy=[…this.state.files];
让objToModify=filesCopy[index];
让objModified={……objToModify,name:/*somename*/,preview:/*somepreview*/}
push(objToModify);
this.setState({files:filesCopy});
}

问题在于上传文件时,文件是文件对象,无法复制文件对象

简单的解决方案是采用@deook的复制解决方案,但也可以在上传时将文件对象转换为JSON对象,只需要我需要的:

  onDrop(files) {
    let f = files.map(file => ({
      name: file.name,
      preview: file.preview
    }));

        this.setState({
            files: this.state.files.length > 0 ? [...this.state.files, ...f] : f,
        });
  }

谢谢但这导致的问题是,我的复制内容仍然是一个文件对象,而原始文件对象现在只是一个普通对象,并失去了一些值。例如`文件(669110){preview:“blob”,processedSrc:“base64”,name:“APRIL2018-D23-LVL13.png”,lastModified:1524493156000,…}`变成{preview:“blob”,processedSrc:“base64”,color:“hex”}啊,好的,我知道了,我已经用一个可能的解决方案编辑了我的答案,只要在地图中创建一个新的文件副本,如果它是你想要“更新”的文件,在看到你的编辑之前,我刚刚尝试减少我的代码负载,我再次遇到了变异问题。基本上现在,我只需将要复制的对象的索引传递给复制函数。我该如何复制对象并编辑它而不发生变异?我已经编辑了我的答案,您可以根据要更改的字段更改
let objModified=..
行,这也是基于您使用的是普通JS对象与文件对象的假设。让我知道这是否正确,否则我可以修改它以处理文件对象很高兴你整理好了…;)