【问题标题】:React state not updating when looping through array循环遍历数组时反应状态不更新
【发布时间】:2018-07-24 09:18:04
【问题描述】:

我在 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(),但被告知状态是不可变的,不应该以这种方式更新 - 但如果我的做法不起作用,我该怎么做?

【问题讨论】:

  • 首先,如果您在组件中管理状态,那么它不是不可变的。你可以以任何你想要的方式改变状态。但是如果你将 props 存储在你的 state 中,那么它不应该被改变,因为 props 是不可变的。我不知道你这样做的方式是什么,但如果你通过维护组件中的状态来做到这一点,那么你可以使用this.state.updatedOrganisationIds.push()
  • 您提到在您的应用程序中使用了redux,那么有什么理由有一个状态,而您可以将所有内容移动到redux?对我来说,拥有 2 个事实来源是维持 state 和 redux 存储之间的数据一致性的苦差事。

标签: reactjs state


【解决方案1】:

有几件事。首先,在您的循环中,只要先前的 updatedOrganisationIds 包含基本上丢弃您迄今为止添加的所有的 oid,您就会重新分配 updatedOrganisationIds。其次,当您根据当前状态更新状态时,您不应该使用这样的状态。第三,当你不使用它返回的数组时,我不确定你为什么要使用 map,如果你以后不打算使用数组,请使用 forEach。

你可以尝试这样的事情:(注意我是如何使用之前的状态的)

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 };
});

【讨论】:

    猜你喜欢
    • 2016-05-14
    • 1970-01-01
    • 2020-03-29
    • 2021-03-25
    • 2016-05-20
    • 2019-08-03
    • 2018-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多