从购物车中删除商品React

时间:2018-02-12 00:23:50

标签: ruby-on-rails arrays reactjs shopping-cart setstate

我对以下代码有2个问题。我想从React中删除购物车中的特定商品。 (后端Rails)。我知道拼接方法是最常用的方法之一,但在我的情况下,它不会删除特定的单击方法,但它会一直删除最后一个项目而不管我单击一个项目。 我的第二个问题是,即使项目以错误的方式删除但仍然被删除,我的Total也不会更新。 这是代码:

import React, { Component } from 'react';
import BasketPic from './images/cart.png';
import StripePayment from './stripePayment';

class MainBasket extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      toggle: true,
      showBasket: false,
      items: this.props.items

    }
    this.toggleBasket = this.toggleBasket.bind(this)
    this.removeItemFromBasket = this.removeItemFromBasket.bind(this)
    console.log(this.state.items)
  }


  toggleBasket(){
   this.setState({toggle: !this.state.toggle});
  }

  showCheckout(){
    this.setState({showBasket: !this.state.showBasket})
  }


  addItemToBasket(itemId){
    fetch(`http://localhost:3000/books/${itemId}`)
    .then( item => item.json())
    .then( item => {
      this.state.items.push(item);
      this.state.total += item.price;
      this.setState(this.state);
    })
  }

  removeItemFromBasket(itemId){
    var itemToBeDeleted = this.state.items.indexOf(itemId)
    var deleted = this.state.items.splice(itemToBeDeleted, 1)
    this.setState(this.state)  
  }

  render(){
    var count_items = this.props.items.length
    var total = this.props.total
    return(
      <div className="basketInfo">
        <div className="mainBasketDiv">
          <img src={BasketPic} onClick={this.toggleBasket} />
          <strong><p className="itemsCart">{count_items}</p></strong>
          <strong><p className="checkOutConf">CheckOut</p></strong> 
          <div className={"toggleDiv-" + this.state.toggle}>
            <h3>{"Total: " + this.props.total}</h3>
            <span><h4>{"Items: " + count_items }</h4></span>

            <hr/>
              {this.props.items.map( item => 
                <div className="animated fadeInRight" key={"item-" + item.id}>
                  <h2>{item.title}</h2> 
                  <h6 onClick={this.removeItemFromBasket} className="remvProd">{"Remove " + item.title}</h6>
                </div>
              )}       
            <button onClick={function(){this.showCheckout()}.bind(this)}> Check out</button>    
          </div>  
        </div>

        <div className="container">
          <div className={"checkOutStripe-" + this.state.showBasket}>
            <div className="totalBar">
              <p className="totalBarTypography"> Total {this.props.items.length} {this.props.items.length < 2 ? "item" : "items"}</p>
              <p className="totalBarTypography"> Total {this.props.total} GBP</p>
            </div>
            <div className="row">
              {this.props.items.map(eachItem => 
                <div className="col-sm" key={"eachItem-" + eachItem.id}>
                  <img src={eachItem.image.url} className="checkOutImg"/>
                  <div className="prodDetails">
                    <h3>{"Product: " + eachItem.title }</h3>
                    <h3>{"Price: " + eachItem.price }</h3>
                  </div>
                </div>
              )}
            </div>
            <div>
              <StripePayment 
                description={'BooksMania'}
                amount={total}
              />
            </div>
          </div>
        </div>
      </div> 
    )
  }
}

// module.exports = MainBasket;
export default MainBasket;

这是我设置总计和项目初始状态的代码:

import React, { Component } from 'react';
import BuyButton from './images/buyButton.jpg';
import MainBasket from './mainBasket';
import CheckOutBasket from './checkOutBasket';
import Reviews from './reviews';

class EachBook extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      newReview: [],
      items: [],
      total: 0
    }
  }

  seeAllReviews(bookId){
    fetch(`http://localhost:3000/books/${bookId}/reviews`)
    .then( reviews => reviews.json())
    .then( reviews => {
      this.setState({
        bookReviews: reviews
      })
    })
  }

  addReview(bookId){ 
    fetch(`http://localhost:3000/books/${bookId}/reviews`,{
      method: 'POST',
      mode: 'cors',
      body: JSON.stringify({comment: this.refs.comment.value}),
      headers: new Headers({
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'X-CSRF-Token' : this.props.parent.props.parent.props.csrf
      }),
      credentials: 'same-origin'
    }).then(response => response.json())
    .catch(error => alert("There is something wrong with this request"))
    .then( response => {
     this.setState({newReview: response})
    })
  }

  addItemToBasket(itemId){
    fetch(`http://localhost:3000/books/${itemId}`)
    .then( item => item.json())
    .then( item => {
      this.state.items.push(item);
      this.state.total += item.price;
      this.setState(this.state);
    })
  }

  render(){
    return(
      <div>

       <MainBasket items={this.state.items}  total={this.state.total} parent={this}/>
        <div className="container"> 
          {this.props.singleBook.map(indBook =>   
            <div className="indBook" key={indBook.id}>
              <h1>{indBook.title}</h1> <br />
              <h2>{"Author: " + indBook.author}</h2> <br />
              <h4>{"Genre: " + indBook.genre}</h4>
              <h4>{"Price: " + indBook.price}£</h4>
              <img src={indBook.image.url} />
              <div className="button"><img src={BuyButton} onClick={function(){this.addItemToBasket(indBook.id)}.bind(this)}/></div>
              <div className="description">{indBook.description}</div>
              <h3>{this.state.newReview.comment}</h3>
              <div> 
                <h4>Leave a new review</h4> 
                  <textarea ref="comment" type="text" placeholder='Tell us your thoughts '></textarea>
                  <button onClick={ function(){this.addReview(indBook.id)}.bind(this) } >Submit</button>       
              </div>
            </div>
          )}   
        </div> 
      </div>   
    )
  }          
}

export default EachBook;

非常感谢你的帮助!

1 个答案:

答案 0 :(得分:2)

你最大的问题是你在状态中改变items,所以状态不会导致重新渲染。我会考虑使用filter而不是splice,只需设置items就可以了:

removeItemFromBasket(itemId) {
  const items = this.stat.items.filter(item => item.id !== itemId)

  this.setState({ items })
}

addItemToBasket也应该有这个问题。你不应该改变state,因为JavaScript通过引用传递对象。您应该在this.state.total方法中使用this.props.total而不是render

希望有所帮助。