【问题标题】:How to disable only selected button onClick inside .map() function of REACT js如何在 REACT js 的 .map() 函数中仅禁用选定的按钮 onClick
【发布时间】:2019-04-17 19:17:12
【问题描述】:

我在 REACT js 中有购物应用程序。我使用 .map() 函数显示所有产品,并在每个产品前面显示“添加到购物车”按钮。当点击添加到购物车 btn 时,它会将点击的产品 ID 添加到本地存储中,然后我通过检索 ID 在 Shopping Cart 中显示这些选定的产品来自 localStorage。这一切都很好

现在我想要的是在单击一次时禁用“添加到购物车”按钮(仅适用于选定的产品)。我通过设置状态做到了这一点,但它实际上禁用了所有产品前面的所有“添加到购物车”按钮而不是只禁用选定的按钮。

我搜索了很多这个问题,我得到的解决方案只是将 setState 设置为 true/false 以启用/禁用按钮。我这样做了,但没有用,因为它是为那个页面上的 ALL 产品做的。请帮我做什么。

这是我的 REACT JS 代码:

export default class SpareParts extends Component
{
  constructor()
  {
      super()
      this.state = {
        spareParts: [],
        cart: [],
        inCart: false,
        disabledButton: false
      };

      this.ViewDeets = this.ViewDeets.bind(this);
      this.AddToCart = this.AddToCart.bind(this);
  }


  ViewDeets= function (part)
  {
    this.props.history.push({
                pathname: '/partdetails',
                 state: {
                    key: part
                }
            });
  }

  AddToCart(param, e)
  {
  
    var alreadyInCart = JSON.parse(localStorage.getItem("cartItem")) || [];
    alreadyInCart.push(param);
    localStorage.setItem("cartItem", JSON.stringify(alreadyInCart));

    this.setState({
      inCart: true,
      disabledButton: true
    })

  }

  
  componentDidMount()
  {
    console.log("Showing All Products to Customer");

        axios.get('http://localhost/Auth/api/customers/all_parts.php', {
        headers: {
         'Accept': 'application/json, text/plain, */*',
          'Content-Type': 'application/json'
         }} )
       .then(response =>
       {
       this.setState({
              spareParts :response.data.records
            });
       })
         .catch(error => {
         if (error) {
           console.log("Sorry Cannot Show all products to Customer");
           console.log(error);
         }
           });
  }

render()
  {
    return (

<div id="profileDiv">

{this.state.spareParts.map(  part =>


<Col md="3" lg="3" sm="6" xs="6">
  <Card>

  <Image src={"data:image/png[jpg];base64," +  part.Image}
  id="partImg" alt="abc" style={ {width: "90%"}} />

  <h4>  {part.Name} </h4>
  <h5> Rs. {part.Price}  </h5>
  <h5> {part.Make} {part.Model} {part.Year} </h5>
  <h5> {part.CompanyName} </h5>

<button
    onClick={()=> this.ViewDeets(part) }>
    View Details
</button>

<button onClick={() => this.AddToCart(part.SparePartID)}
   
   disabled={this.state.disabledButton ? "true" : ""}>
  {!this.state.inCart ? ("Add to Cart") : "Already in Cart"}
</button>

  </Card>
</Col>

)}

</div>

);
  }
}

【问题讨论】:

    标签: javascript reactjs onclick setstate map-function


    【解决方案1】:

    您一次只需要禁用一个按钮吗?如果是这样,请将您的状态更改为不是布尔值,而是指示哪个按钮被禁用的数字。然后在渲染中,仅当您正在渲染的按钮具有与在状态中找到的相同索引时才禁用。

    this.state = {
       disabledButton: -1
       // ...
    }
    
    // ...
    
    AddToCart(index, param, e) {
      //...
      this.setState({
        inCart: true,
        disabledButton: index
      })
    }
    
    
    // ...
    
    {this.state.spareParts.map((part, index) => {
       // ...
      <button onClick={() => this.AddToCart(index, part.SparePartID)}
        disabled={this.state.disabledButton === index}>
        {!this.state.inCart ? ("Add to Cart") : "Already in Cart"}
      </button>
    })}
    

    如果每个按钮需要同时独立禁用,请将您的状态更改为与备件长度相同的布尔数组,并在渲染方法中查找每个按钮是否应该禁用在那个数组中。

    this.state = {
      spareParts: [],
      disabledButtons: [],
      // ...
    }
    
    // ...
    
    axios.get('http://localhost/Auth/api/customers/all_parts.php', {
      headers: {
        'Accept': 'application/json, text/plain, */*',
        'Content-Type': 'application/json'
        }} )
    .then(response =>{
      this.setState({
        spareParts: response.data.records,
        disabledButtons: new Array(response.data.records.length).fill(false)
      });
    });
    
    // ...
    
    AddToCart(index, param, e) {
      //...
      this.setState(oldState => {
        const newDisabledButtons = [...oldState.disabledButtons];
        newDisabledButtons[index] = true;
        return {
          inCart: true,
          disabledButtons: newDisabledButtons,
        }
      });
    }
    
    // ...
    
    {this.state.spareParts.map((part, index) => {
       // ...
      <button onClick={() => this.AddToCart(index, part.SparePartID)}
        disabled={this.state.disabledButtons[index]>
        {!this.state.inCart ? ("Add to Cart") : "Already in Cart"}
      </button>
    })}
    
    

    【讨论】:

    • 感谢您的回复。是的,我想同时单独禁用每个按钮。那么如何将状态更改为布尔数组?请详细说明。
    • @YellowMinion 我在一个带有数组的示例中添加了
    • 再次感谢。如何在 AddToCart 方法中禁用单击的按钮?
    • 您使用一个将索引切换为 true 的数组设置状态。我在一个示例中进行了编辑。
    • 惊人且非常有用的答案。正是我要找的东西,但不知何故我不知道如何立即更新按钮。我有一个包含很多按钮的表格,并且它们仅在我单击该行而不是在单击按钮后重新呈现。任何提示如何触发现在应该禁用的按钮的重新渲染?
    猜你喜欢
    • 2022-01-11
    • 2021-06-10
    • 2020-12-31
    • 2022-09-27
    • 1970-01-01
    • 2013-02-09
    • 1970-01-01
    • 2021-05-20
    • 2020-09-28
    相关资源
    最近更新 更多