我正在尝试生成一组UI控件,因为它们正在呈现,结果状态包含重复的条目。有没有一种好方法可以防止这种情况发生?
每次呈现组件时都会触发此代码。有多个表具有类似的控件,我使用它来获取每个控件的最大行数:
const newcontrols: LoadedCtrls = {
"itemCtrlType": controlType,
"rowsCount": numberRows,
};
if (this.state.loadedcontrols.length == 0) {
this.setState({
loadedcontrols: [...this.state.loadedcontrols, newcontrols]
})
}
for (var i = 0; i < this.state.loadedcontrols.length; i++) {
if (this.state.loadedcontrols[i].itemCtrlType == controlType) {
if (this.state.loadedcontrols[i].rowsCount < numberRows) {
this.setState({
loadedcontrols: [...this.state.loadedcontrols.slice(0, i), newcontrols, ...this.state.loadedcontrols.slice(i)]
})
}
}
else {
this.setState({
loadedcontrols: [...this.state.loadedcontrols, newcontrols]
})
}
}
控制台中的结果如下:
[{"itemCtrlType":"map1","rowsCount":2},{"itemCtrlType":"map2","rowsCount":3},{"itemCtrlType":"location","rowsCount":5},{"itemCtrlType":"map2","rowsCount":3},{"itemCtrlType":"monitor","rowsCount":7},{"itemCtrlType":"monitor","rowsCount":7}]
我试图使用具有不变性的良好实践,但似乎仍然使用重复项启动setState,我知道它是一个异步操作。那么有办法防止这种情况吗?
编辑:每次组件的获取功能输出数据时触发该功能,并在组件中设置状态:
.then(data => {
this.setState({
results: data,
loading: false,
}, () => {
this.finishLoad(this.state.controlType, this.state.customerId, data.length);
});
});
答案 0 :(得分:1)
使用setState()
会导致非常不确定的行为;有两个原因:
setState()
不应该用作同步调用(即,您依赖于state
立即更新)。 setState()
可能没有预期的行为(因为1。)。您可能会考虑更一般的模式:
let localState=this.state;
// Rely on and modify localState, as desired
this.setState(localState) // Set final state and trigger potential re-render
您可能不需要在初始setState()
调用中指定回调,因为状态更改是批处理的,并且隐式调用下一个呈现。
以下阅读可能有用setState() State Mutation Operation May Be Synchronous In ReactJS