【问题标题】:Delete an object from array React从 React 数组中删除一个对象
【发布时间】:2018-04-29 11:08:20
【问题描述】:

我正在尝试删除我所在州的数组中的一个对象。我想通过对地图函数中的项目使用 onclick 处理程序来做到这一点。

所以当我点击一个特定的项目时,我已经尝试了很多事情。我通过尝试从 map 函数中传递项目然后过滤掉数组(不包括作为参数提供的项目)来尝试过滤器函数,我尝试了 splice,但似乎都不起作用。使用拼接,它总是删除最后一个项目而不是我点击的项目。

我没看到什么?我知道有很多类似的问题,但我已经尝试了很多那里的答案,但似乎没有任何效果。

过滤尝试

JSX

{this.state.product.ingredients.map((item) => {
  return (
     <p className="text-xs text-white bg-brand rounded p-4 mt-2 mb-2 mr-2 inline-block cursor-pointer" key={item.name} onClick={({item}) => this.deleteTag({item})}>{item.name}</p>
  );
})}

方法

deleteTag(item) {

    let product = {...this.state.product};

    product.ingredients.filter((ingredient) => {
        return ingredient !== item;
    });

    this.setState({product: product});
}

拼接

JSX

{this.state.product.ingredients.map((item) => {
  return (
     <p className="text-xs text-white bg-brand rounded p-4 mt-2 mb-2 mr-2 inline-block cursor-pointer" key={item.name} onClick={this.deleteTag}>{item.name}</p>
  );
})}

方法

deleteTag(e) {

    let product = {...this.state.product};

    var index = product.ingredients.indexOf(e.target.value)

    product.ingredients.splice(index, 1);

    this.setState({product: product});

}

具有一个对象的数组示例(对象/项与另一个函数一起添加)

ingredients: [{name: 'Salad', value: 1}],

【问题讨论】:

  • 对于您的拼接,为什么 e 不是 item ?将其记录到控制台会发现它不是您认为的那样。然后在数组中索引item

标签: javascript reactjs


【解决方案1】:

我不确定您是否正确更新了状态,而是对其进行了变异。你可以试试这个:

deleteTag(item) {
    this.setState(prevState => { 
      return {
        product: {
           ...prevState.product,
           ingredients: prevState.product.ingredients.filter((ingredient) => ingredient !== item)
        }
      } 
    });
}

编辑您的 onClick 以传递来自map 的item:

onClick={() => this.deleteTag(item)}

【讨论】:

  • 嗯,它返回一个错误,说编译失败。我猜是语法错误?
  • 在哪一行?你确定你已经保存了所有文件吗?
  • @Gijsberts 我认为是一个额外的括号导致了这种情况,请尝试更新后的 sn-p。
  • 好吧,我猜这个函数可以工作,只是它没有更新任何东西。所以我猜过滤器函数出错了,因为我猜项目是未定义的或什么的......回调有问题。我通过了吗? (项目)
  • @Gijsberts 我明白了,您需要更新您的 onClick 处理程序。签出编辑。
【解决方案2】:

filter 返回一个新数组,而不是在原地修改数组。

{...this.state.product} 只创建一个浅拷贝,因此无论如何您都不应该修改product.ingredients,这也是您第二次尝试失败的原因。

试试这个:

this.setState(prevState => ({
  product: { ...prevState.product, ingredients: prevState.product.ingredients.filter(...) },
}));

【讨论】:

  • 嗯,它返回一个错误,说编译失败。我猜是语法错误?
  • 用你原来的filter参数替换filter(...);我使用... 作为实际逻辑的占位符。
【解决方案3】:

您需要将item 传递给您的回调。您当前正在使用event.target.value,但您的&lt;p&gt; 元素没有value。使用bind 部分应用您的回调。

JSX:

{this.state.product.ingredients.map((item) => (
  <p
    className="text-xs text-white bg-brand rounded p-4 mt-2 mb-2 mr-2 inline-block cursor-pointer"
    key={item.name}
    onClick={this.deleteTag.bind(item)}>
    {item.name}
  </p>
))}

回调的第一个参数将是您的item 对象,因为部分函数应用程序,它将不再是点击事件。 (如果还需要点击事件,则为第二个参数。)

方法:

deleteTag(item, /* event */) {
  let product = {...this.state.product};
  const index = product.ingredients.indexOf(item.value)

  product.ingredients.splice(index, 1);
  this.setState({product: product});
}

【讨论】:

  • 嘿。得到与以前相同的结果,由于某种原因,当我单击它时,它将删除/删除数组中的最后一个对象,而不是我单击的那个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-18
  • 1970-01-01
  • 2016-11-08
  • 2021-03-21
相关资源
最近更新 更多