在 REACT 中复制而不引用状态对象

时间:2021-05-14 06:48:52

标签: reactjs typescript reference state setstate

尝试创建状态对象的副本,更改它,然后使用 setState() 设置它。

但是,我无法复制该对象,而是创建了一个引用。这意味着当我编辑它时,我直接编辑状态对象,这意味着 setState() 不会重新渲染,因为从我编辑对象到我尝试运行 setState() 时实际上没有任何变化。

我已经能够用一个数组来做到这一点,它包含在我下面的代码中。

// This is my state
interface IEditPanelState {
    currentFiles: SearchResults;
    newFiles: File[];
}


// This is my function
   public async cacheFiles(files: File[]) {
        // This works
        let cachedFiles = [...this.state.newFiles];
        // This is creating a reference. How to copy Searchresults??
        let currentFiles = this.state.currentFiles;
    
        for(let file of files) {
          cachedFiles.push(file);
          currentFiles.PrimarySearchResults.push({
            Title: file.name
          });
        }

        console.log(currentFiles);
        console.log(cachedFiles);
        console.log(this.state.newFiles);

        this.setState({
            newFiles: cachedFiles,
            currentFiles: currentFiles
        });
   } 

2 个答案:

答案 0 :(得分:1)

您能解释一下必须对状态进行深度克隆的主要需求吗?如果数组大小增加,它可能没有性能,也可能是不必要的。

此外,由于您的新状态依赖于以前的状态,如果您遵循那里的功能约定可能会有所帮助。像下面的东西


// this has the logic to extract current files from present state
const getCurrentFiles = (currState) => { ... };

const cacheFiles = (files) => {
  this.setState((currentState) => {
    const currentFiles = getCurrentFiles(currentState);
    return ({
      newFiles: [...currState.currentFiles, ...files],
      currentFiles
    });
  })
}

链接到 setState 功能约定的文档 - setState documentation

答案 1 :(得分:0)

@SarangPM 作为评论回答了这个问题。

答案如下:

<块引用>

let currentFiles = this.state.currentFiles; 将始终创建一个引用。对于浅拷贝,您可以使用扩展运算符,对于深度克隆,您可以使用 lodash 中的深度克隆函数。

我安装了 lodash,遇到了一些问题,但最终修复了它。在下面查看我的评论。

<块引用>

我刚刚使用 npm 安装了它。它说要使用:import { _ } from 'lodash'; 导入,但这会导致以下错误:'_' can only be imported by turning on the 'esModuleInterop' flag and using a default import。编辑:nvm,我使用:import { cloneDeep } from 'lodash';

感谢@SarangPM 回答我的问题并解决了我的问题。 我将此添加为答案,因为@SarangPM 没有。

EDIT: Please read the answer from @jaybhatt, since using DeepClone isn't optimal