如何在状态内的数组中正确添加和删除特定项?

时间:2019-01-23 22:41:01

标签: javascript reactjs

我正在尝试实现一些功能,以允许将复选框的名称在组件状态下推送到数组,并且在取消选中复选框时也删除该名称,我可以将其仅推送到数组很好,它是从中删除我遇到麻烦的项目。

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

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

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

2 个答案:

答案 0 :(得分:3)

根据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,它使用数组的浅表副本,但我认为这更易读。

答案 1 :(得分:1)

一个简单的解决方案是.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)
    });
  }
};

编辑:西班牙人与我同时发布了相同的解决方案,但由于实现略有不同,我将在此保留。