通过单击React删除映射的元素

时间:2019-09-21 17:54:56

标签: javascript arrays reactjs state

在我的状态下,我有一个数组,该数组是我在render函数中映射的:

this.state = {
        newItem: {
            name: "",
            amount: 0
        },
        products: [
            {
                name: "Item",
                amount: 5
            },
            {
                name: "Item",
                amount: 5
            },
            {
                name: "Item",
                amount: 5
            }
        ]
    }

我想通过单击该元素的按钮从阵列产品中删除该元素。但是我试图做的一切都失败了。我进行了很多搜索,从逻辑上找到了最常见的解决方案,但是它也没有起作用。这是删除功能:

删除功能

delete(e) {
  this.setState(prevState => ({ products: prevState.products.filter((product) => {
      return product !== e.target.value
  })}))
  console.table(this.state.products)
}

映射的JSX代码

            {
                this.state.products.map((item, index) => {
                    return(
                        <div key={index}>
                            <input readOnly value={this.state.products[index].name} type="text" />
                            <button disabled>-</button>
                            <input readOnly value={this.state.products[index].amount} type="number" />
                            <button disabled>+</button>
                            <button onClick={(e) => this.delete(e)}>Delete</button>
                        </div>
                    )
                })
            }

4 个答案:

答案 0 :(得分:2)

您需要将该元素的索引传递到delete中,该元素将按如下所示删除。

<button onClick={() => delete(index)}>Delete</button>

然后,您可以轻松删除该元素。

delete = index => {
  this.setState(prevState => 
    ({
        products: prevState.products.filter((product, i) => i !== index)
    })
  );
}

答案 1 :(得分:1)

有关如何在映射列表上设置项目特定按钮的简化示例:

PagerAdapter

答案 2 :(得分:1)

这里是解决方案和工作示例,https://codesandbox.io/s/dawn-tdd-js8yz

state = {
    newItem: {
        name: "",
        amount: 0
    },
    products: [
        {
            name: "Item1",
            amount: 5
        },
        {
            name: "Item2",
            amount: 5
        },
        {
            name: "Item3",
            amount: 5
        }
    ]
}

  delete(e: any) {
    
    var products = this.state.products.filter((product) => {
      return product.name !== e.name
    });

    console.log(products)

    this.setState({products: products})
    console.table(this.state.products)
  }

  render() {
    const { products } = this.state;
    return (
      <>
      {products.map((x, index) => {
        return <div key={index}>
        <input readOnly value={this.state.products[index].name} type="text" />
        <button disabled>-</button>
        <input readOnly value={this.state.products[index].amount} type="number" />
        <button disabled>+</button>
        <button onClick={this.delete.bind(this, x)}>Delete</button>
    </div>
      })}
      </>
    )
  }

答案 3 :(得分:1)

请注意,setState异步,因此在调用console.log(this.state.products)之后立即使用setState不会打印更新的产品。您可以在setState的第二个参数中传递一个回调,一旦setState完成,它将执行。

另一个问题来自delete函数。您正在使用e.target.value,它是一个空字符串,因为按钮没有值。

您可以使用以下代码解决此问题:

delete(product) {
  this.setState(prevState => ({
    products: prevState.products.filter(p => p !== product)
  }), 
  () => console.log(this.state.products));
}

在JSX代码中,我将产品传递到delete函数的第一个参数中:

{
  this.state.products.map((product, index) => (
    <div key={index}>
      <input readOnly value={product.name} type="text"/>
      <button disabled>-</button>
      <input readOnly value={product.amount} type="number"/>
      <button disabled>+</button>
      <button onClick={() => this.delete(product)}>Delete</button>
    </div>
  ))
}