我正在尝试使用以下代码更新状态:
handleCheckBox = () => {
this.setState(({isCheckd}) => ({isCheckd: !isCheckd, isEnable: !isCheckd}), () =>
this.props.untracked.forEach((item) => this.setState({ [item.resumeId]: this.state.isCheckd })),
this.props.tracked.forEach((item) => this.setState({ [item.resumeId]: this.state.isCheckd }))
);
}
当我尝试使用forEach
函数进行更新时。在第一个循环中,状态会更新,因为您看到条件相同。但在这第一个中得到改变,但在第二个中没有得到改变。如果我更改了它们的写入顺序,则以第一个状态为准,而第二个状态不变。
handleTableCheckboxChange = (e, type) => {
this.setState({
[e.target.name]: e.target.checked
}, () => {
const checkedItems = this.props[type].filter((item) => this.state[item.resumeId])
this.setState({
isCheckd: checkedItems.length === this.props[type].length ? true : false,
isEnable: checkedItems.length > 1 ? true : false
});
});
}
如何防止这种情况发生?
答案 0 :(得分:2)
正如我在对上一个问题的评论中所说,您正在打破fundamental rules of React之一:如果要基于现有状态设置状态 ,则您必须< / strong>使用setState
的回调版本,而不是将对象传递给的版本。
看那个代码,这样做看起来像这样:
handleCheckBox = () => {
this.setState(
({isCheckd}) => ({isCheckd: !isCheckd, isEnable: !isCheckd}),
() => this.setState(({isCheckd}) => {
const newState = {};
for (const item of [...this.props.untracked, ...this.props.tracked]) {
newState[item.resumeId] = isCheckd;
}
return newState;
})
);
}
但是,跳出了一些奇怪的事情:
目前尚不清楚为什么要在外部setState
的完成处理程序中再次调用setState
。
不清楚当您对tracked
和untracked
进行相同操作时为何拥有它们。
如果您可以在一个状态下进行更新,那可能会更好:
handleCheckBox = () => {
this.setState(({isCheckd}) => {
const newState = {
isCheckd: !isCheckd,
isEnable: !isCheckd
};
for (const item of [...this.props.untracked, ...this.props.tracked]) {
newState[item.resumeId] = isCheckd;
}
return newState;
});
}
关于您更新的问题,handleTableCheckboxChange
存在相同的问题(基于将对象传递到setState
的现有状态来设置状态),因此适用相同的解决方案(使用回调版本):
handleTableCheckboxChange = ({target: {name, checked}}, type) => {
this.setState(prevState => {
const newState = {[name]: checked};
const checkedItems = this.props[type].filter((item) => prevState[item.resumeId]);
newState.isCheckd = checkedItems.length === this.props[type].length;
newState.isEnable = checkedItems.length > 1;
return newState;
});
};
(注意,我已经从设置? true : false
和isCheckd
的行中删除了isEnable
。===
和>
已经给您一个布尔值,在那里添加条件运算符毫无用处。)