Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 反应:使用spead运算符设置状态似乎可以直接修改状态_Reactjs - Fatal编程技术网

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
处于同一级别,而不是嵌套。如果你高兴,我能得到一张绿色支票吗