我有一个购物车中有反应( 未使用Redux ),其中每个项目前面都有“数量”输入字段。默认情况下,数量为1。每个项目的总价格是该项目的信息(单价* 1)。现在,如果用户更新“数量”值,则需要更新(单价*数量)。我的代码正在执行此操作,但是问题是当我更新一个项目的数量时,它会更新价格,很好,但是当我更新另一个项目的数量时,先前更新的价格将重置为默认值 (返回单价)。
我搜索了很多但没有用。大多数人都使用redux,但我不想使用它。因此,如果您看到解决方案,请帮我,因为我想保持所有更新的价格。
export default class Cart extends Component
{
constructor(props) {
super(props);
this.state = {
data:[],
customer: '',
redirectToReferrer: false,
cart: [],
cartItems: [],
qty: '',
clicked: '' };
this.onChangeQty = this.onChangeQty.bind(this);
}
componentDidMount() {
const retrieved = localStorage.getItem("cartItem");
const arr = JSON.parse(retrieved);
axios.post('http://localhost/Auth/api/customers/show_cart.php', arr,
{
headers: {'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'}
} )
.then(response => {
this.setState({
cartItems :response.data.records
});
})
.catch(error => {
if (error) {
console.log("Error"); }
});
}
onChangeQty(sid,e)
{
this.setState({
clicked: sid,
qty: e.target.value })
}
render()
{
return (
<div id="profileDiv">
<Col md="12" lg="12" sm="12" xs="12">
<h1> <b> Your Shopping Cart </b> </h1>
<Table>
<thead>
<tr className="text-center">
<th> Item# </th>
<th> Image </th>
<th> ID</th>
<th> Name</th>
<th> Unit Price </th>
<th> Quantity </th>
<th> Total Price </th>
</tr>
</thead>
<tbody>
{this.state.cartItems.map( (item, i) =>
<tr>
<td className="text-center">
<h4 key={i}> {i}</h4>
</td>
<td className="text-center">
<Image src={"data:image/png[jpg];base64," + item.Image}
id="cartImage" alt="abc" />
</td>
<td className="text-center">
<h4>{item.SparePartID}</h4>
</td>
<td className="text-center">
<h4> {item.Name}</h4>
</td>
<td className="text-center">
<h4 >{item.Price} </h4>
</td>
<td className="text-center">
<h4 key={item.SparePartID}>
<input className="text-center"
type="number"
min="1"
onChange={(e) => this.onChangeQty(item.SparePartID, e)}
/>
</h4>
</td>
<td className="text-center">
<h4 key={item.SparePartID}>
{
this.state.clicked == item.SparePartID ?
(item.Price*this.state.qty) : item.Price
}
</h4>
</td>
</tr>
)} </tbody>
</Table>
</Col>
</div> ); }
}
答案 0 :(得分:0)
您对每件商品都使用相同的状态,因此对数量所做的每一次更改都会修改您的状态,因此每件商品的商品价格都会改变。无需为此使用redux。您可以做两件事:将项目逻辑移至子组件,因此,每个项目都将具有自己的状态,或者通过修改状态来处理诸如{name:'itemname', price:itemPrice etc etc}
之类的对象数组,只需编辑一个特定商品或改善您的购物车商品:[]数量多。
编辑:
现在您可以尝试渲染n个我称为ChartItem的子组件,它们将收到{...item}
你可以的。通过this.props.yourItemProp
{this.state.cartItems.map( (item, i) => <ChartItem key={i} {...item} />}
现在,您可以在每个ChartItem中定义一个私有状态并使用它。如果要与父组件通信,只需将子函数
传递给子组件 {this.state.cartItems.map( (item, i) => <ChartItem key={i} {...item}
onItemSomething={this.handleOnItemSomething}
/>}
因此,您可以调用this.props.onItemSomething与您的父组件进行通讯
答案 1 :(得分:0)
我认为您的问题是您管理cartItem的方式。在onChangeQty中,您应该遍历this.state.cartItems并找到具有选定sid的项目,可以使用
onChangeQty (sid, {target:{value}}){
let {cartItems } = this.state
let ind = cartItems.findIndex( o => o.sid === sid) //get index and
//update the
// qty of
// that element of the cartItems
// array ,
cartItems[ind].sid + = value
this.setState({cartItems})
}
答案 2 :(得分:-1)
您需要做的是,当您获得购物车物品时,请仔细检查每个物品并为其添加数量。并为所有产品的总计添加状态总计。
public static function getCategoryList()
{
$db = Db::getConnection();
$lang = self::Language();
$categoryList = [];
$result = $db->query("SELECT content.id, content.title$lang,content.slug$lang, content.sub_category_id, category.slug$lang FROM blog_category AS content LEFT JOIN blog_category AS category ON content.sub_category_id = category.id WHERE content.status='1' ORDER BY content.sort_order ASC");
foreach($result as $row){
$categoryList[] = [
'id' => $row[0],
'title' => $row[1],
'slug' => $row[2],
'sub_category' => $row[4],
];
}
return $categoryList;
}
OnChange方法应找到所选产品并更新其数量和totalPrice:
<?php foreach ($category as $categoryItem): ?>
<h4><a href="/blog/<?php if ($categoryItem['sub_category']) echo $categoryItem['sub_category'] . '/'; ?><?php echo $categoryItem['slug']; ?>"><?php echo $categoryItem['title']; ?></a></h4>
<p><?php echo $categoryItem['id']; ?></p>
<?php endforeach; ?>
并且在html中,您可以将总价格显示为
constructor(props) {
super(props);
this.state = {
data:[],
customer: '',
redirectToReferrer: false,
cart: [],
cartItems: [],
totalPrice: 0
clicked: '' };
this.onChangeQty = this.onChangeQty.bind(this);
}
componentDidMount() {
const retrieved = localStorage.getItem("cartItem");
const arr = JSON.parse(retrieved);
axios.post('http://localhost/Auth/api/customers/show_cart.php', arr,
{
headers: {'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'}
} )
.then(response => {
let myItems = [];
response.forEach(item => {
myItems.push({id: item.id, name: item.name, qty: 1, price: item.price, total: item.price});
})
this.setState({
cartItems :myItems
});
})
.catch(error => {
if (error) {
console.log("Error"); }
});
}
如果您想总计每个项目,则只需按以下方式进行检查即可:
onChangeQty(sid,e)
{
const items = this.state.cartItems;
const item = items.find(item => item.id === sid);
const index = items.indexOf(item);
item.qty = e.target.value;
item.total = item.qty * item.price;
items[index] = index;
let totalPrice = 0;
items.forEach(item => {
totalPrice += item.qty * item.price;
});
this.setState({
cartItems: items,
totalPrice
});
}