遍历数组时反应状态不更新

时间:2018-07-24 09:18:04

标签: reactjs state

我在redux表单上有一个嵌套的复选框列表,这些复选框是按地区(英格兰,威尔士,苏格兰)进行组织的,然后是位于相关区域中的组织。

我已经在我的组件中编写了一个函数,每当选中一个复选框时就会触发该函数,它会更新我所选的复选框状态并添加新ID。同样,取消选中该复选框也会删除ID。

但是,用户可以做的另一件事是检查顶层区域,该区域会打开列表并自动选中下面的所有框,从而使选择所有内容变得容易,而不是单独进行选择。但是,这些自动选中的复选框ID不会进入状态,因此当某人决定取消选中该区域中的某个复选框时,他们将全部取消选中,仅单击的复选框会重新选中-我进行了一些调试,发现该状态不包括这些复选框

这是我编写的用于遍历区域内ID并尝试将其添加到状态的代码:

const organisationIdsToAdd = regionalOrganisationIds.filter(organisationId => {
    return !this.state.regionOrganisationsMapping[toggledRegionId].includes(organisationId);
});

let updatedOrganisationIds = [];

organisationIdsToAdd.map(oid => {
    if(!this.state.updatedOrganisationIds.includes(oid)) {
        updatedOrganisationIds = [...this.state.updatedOrganisationIds, oid];
    } else {
        updatedOrganisationIds = this.state.updatedOrganisationIds.filter(orgId => orgId !== oid);
    }
});

此代码发生在名为_toggleRegionSelection()的函数中,该函数在单击区域复选框时运行。区域ID作为参数传递。完成此操作后,我将设置状态:

this.setState({ updatedOrganisationIds });

然后运行:

this.props.onOrganisationChange(organisationIdsToAdd);

要将呼叫发送回表单并更新复选框的值。但是,状态始终会变回空白(只要用户单击页面加载区域)。该地区本身并不需要处于州内,只需组织即可。

我尝试使用this.state.updatedOrganisationIds.push(),但被告知状态是不可变的,不应以这种方式更新-但是,如果我无法做到这一点,该怎么办? >

1 个答案:

答案 0 :(得分:1)

A couple of things. Firstly in your loop you reassign updatedOrganisationIds whenever the previous updatedOrganisationIds contains the oid which basically throws away all of the ones you've added so far. Secondly you shouldn't use the state like that when you are updating state based on the current state. Thirdly I'm not sure why you are using map when you don't then use the array it returns, use forEach if you don't intend on using the array afterwards.

You could try something like this: (notice how I use the previous state)

const organisationIdsToAdd = regionalOrganisationIds.filter(organisationId => {
  return !this.state.regionOrganisationsMapping[toggledRegionId].includes(organisationId);
});

this.setState((prevState) => {
  let updatedOrganisationIds = Object.assign([], prevState.updatedOrganisationIds);
  organisationIdsToAdd.forEach((oid) => {
    const index = updatedOrganisationIds.indexOf(oid);
    if (index === -1) {
      updatedOrganisationIds.push(oid);
    } else {
      updatedOrganisationIds.splice(index, 1);
    }
  });
  return { updatedOrganisationIds };
});