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