我对以下代码有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;
非常感谢你的帮助!
答案 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
。
希望有所帮助。