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

Copying and not referencing state object in REACT

正在尝试创建状态对象的副本,更改它,然后使用 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
        });
   } 

您能解释一下必须对状态进行深度克隆背后的主要需求吗?如果数组大小增加并且也可能是不必要的,它可能无法执行。

此外,由于您的新状态取决于之前的状态,因此如果您遵循那里的功能约定可能会有所帮助。如下所示


// 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
    });
  })
}

Link 至 setState 功能约定的文档 - setState documentation

这已由@SarangPM 作为评论回答。

答案如下:

let currentFiles = this.state.currentFiles; will always create a reference. For a shallow copy, you can use the spread operator and for a deep clone, you can use deep clone function from lodash.

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

I just installed it using npm. It says to import using: import { _ } from 'lodash'; However this results in the following error: '_' can only be imported by turning on the 'esModuleInterop' flag and using a default import. EDIT: nvm, I got it working using: import { cloneDeep } from 'lodash';

非常感谢@SarangPM 回答我的问题并解决了我的问题。 我添加这个作为答案,因为@SarangPM 没有。