正在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
});
})
}

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

@SarangPM已对此进行了评论回复。

答案是:

let currentFiles = this.state.currentFiles;将始终创建引用。对于浅拷贝,可以使用spread运算符;对于深度克隆,可以使用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没有。

编辑:请阅读@jaybhatt的答案,因为使用DeepClone不是最佳

最新更新