【问题标题】:How to correctly add and remove specific items from an array within state?如何在状态内的数组中正确添加和删除特定项目?
【发布时间】:2019-01-23 22:41:00
【问题描述】:

我正在尝试实现一些功能,允许将复选框的名称推送到组件状态下的数组中,并且在未选中复选框时删除该名称,我可以推送到数组中好的,它正在从中删除我遇到问题的项目。

我尝试过使用 splice,但我遇到的问题是数组似乎落后了一个动作,因此不允许我拼接出正确的项目。

handleCheckboxChange = event => {
  if (event.target.checked) {
    this.setState({
      check: [...this.state.check, event.target.name]
    });
} else if (!event.target.checked) {
    let index = this.state.check.indexOf(event.target.name);
    this.setState({
      check: this.state.check.splice(index, 1)
    });
  }
};

预期结果是当用户选中或取消选中相应的复选框时,将在数组中添加和删除项目。

【问题讨论】:

  • 请记住,setState() 是异步的。它很可能会如您所愿发生,只是不在您期望的时间范围内。

标签: javascript reactjs


【解决方案1】:

根据documentation of splice,返回删除的项目。

包含已删除元素的数组。如果仅删除一个元素,则返回一个包含一个元素的数组。如果没有元素被移除,则返回一个空数组。

所以当你这样做时:

   this.setState({
      check: this.state.check.splice(index, 1)
    });

你基本上是直接修改this.state.check,在上面使用拼接,然后用this.setState({ check: [removed items] })设置。

您不应该直接修改状态变量,而应该这样做:

this.setState({
     check: this.state.check.filter((item, i) => {
          return index !== i;
     })
})

filter 创建一个新数组,不要修改当前数组。您也可以使用slice,它使用数组的浅拷贝,但我认为这更具可读性。

【讨论】:

    【解决方案2】:

    一个简单的解决方案是.filterMDN reference.

    您还应该注意.splice 正在改变数组,这意味着您正在使用 .splice 改变状态对象,然后使用 setState() 更改状态,这意味着您对其进行了两次更改。我相信你想避免突变,只用 setState() 改变它。

    试试这个解决方案,(添加了一些关于格式化的意见):

    handleCheckboxChange = event => {
      const {checked, name} = event.target
      if (checked) {
        this.setState({
          check: [...this.state.check, name]
        });
    } else {
        this.setState({
          check: this.state.check.filter(item => item !== name)
        });
      }
    };
    

    编辑:西班牙人与我同时发布了相同的解决方案,但我将把它留在这里,因为实现略有不同。

    【讨论】:

      猜你喜欢
      • 2022-06-10
      • 2019-10-13
      • 2019-12-30
      • 2020-12-15
      • 1970-01-01
      • 2016-07-19
      相关资源
      最近更新 更多