Reactjs 反应:使用spead运算符设置状态似乎可以直接修改状态
我正在“响应过滤器属性”中创建一个页面,该属性在我的Reactjs 反应:使用spead运算符设置状态似乎可以直接修改状态,reactjs,Reactjs,我正在“响应过滤器属性”中创建一个页面,该属性在我的状态中定义,并带有isChecked,如下所示: this.state = { countries: [ { "id": 1, "name": "Japan", "isChecked": false }, { "id": 2, "name": "Netherlands", "isChecked": true }, { "id": 3, "name": "Russia", "isChecke
状态中定义,并带有isChecked
,如下所示:
this.state = {
countries: [
{ "id": 1, "name": "Japan", "isChecked": false },
{ "id": 2, "name": "Netherlands", "isChecked": true },
{ "id": 3, "name": "Russia", "isChecked": true }
//...
],
another: [
{ "id": 1, "name": "Example1", "isChecked": true },
{ "id": 2, "name": "Example2", "isChecked": true },
{ "id": 3, "name": "Example3", "isChecked": false }
//...
],
//... many more
};
我正在创建一个函数resetFilters()
,以在我的状态下将所有isChecked
设置为false:
resetFilters() {
// in reality this array contains many more 'items'.
for (const stateItemName of ['countries', 'another']) {
// here i try to create a copy of the 'item'
const stateItem = [...this.state[stateItemName]];
// here i set all the "isChecked" to false.
stateItem.map( (subItem) => {
subItem.isChecked = false;
});
this.setState({ stateItemName: stateItem });
}
this.handleApiCall();
}
我的问题是:似乎我正在直接修改状态
,这是错误的。即使我的函数似乎可以工作,当我删除行this.setState({stateItemName:stateItem})时
它似乎也会工作,当我控制台记录stateItem
和this.state[stateItemName]
时,它们总是相同的,即使我使用的是应该创建副本的spread操作符。我的问题:这怎么可能/我做错了什么 这是因为扩展语法只进行浅层复制。如果要执行深度复制,还应在每个数组中展开内部对象
for (const stateItemName of ['countries', 'another']) {
const stateItem = [...this.state[stateItemName]];
const items = stateItem.map( (subItem) => ({
...subItem,
isChecked: false,
}));
this.setState({ [stateItemName]: items });
}
我认为您的代码可以进一步缩减,例如,一种方法可以是:
function resetFilters() {
const targetItems = ['countries', 'another'];
const resetState = targetItems.reduce((acc, item) => ({
...acc,
[item]: this.state[item].map(itemArray => ({
...itemArray,
isChecked: false
}))
}), {})
this.setState(state => ({ ...state, ...resetState }), this.handleApiCall);
}
这里的好处是api调用在状态更新后完成。正确更新当前状态时
让我知道它是如何运作的你能给我一个可生产的例子吗,此外,他还应该在setState中的“stateItemName”周围使用方括号来替换state对象上的正确键,例如.setState({[stateItemName]:items});我喜欢使用一个setState
的想法。无论如何,我的状态没有被更新,即使resetState
似乎是正确的。哎呀,这可能是因为resetState需要被传播。使用前添加三个点。请参阅更新的代码。您是正确的,它在传播时起作用。你知道为什么这需要传播吗?很高兴听到它起作用了。是的,如果没有排列,您将得到this.state.resetState.countries
,简而言之,您希望属性与this.state
处于同一级别,而不是嵌套。如果你高兴,我能得到一张绿色支票吗