我建立了一個 eshop 并努力找到語法以增加“購物車”中產品的數量。我已經成功地將產品“添加到購物車”但是沒有更新添加的產品數量。每次我單擊“addToCart”時,它都會添加產品。我正在使用 redux,所以我知道我應該在 reducer 檔案中撰寫額外的代碼。我的減速器檔案代碼如下:
import { ADD_TO_CART } from './constants'
import { REMOVE_FROM_CART } from './constants'
const initialState = {
cart: [],
}
const ShoppinReducer = (state = initialState, action) => {
switch (action.type) {
case ADD_TO_CART:
const newCart = [...state.cart]
newCart.push(action.payload)
return {
...state,
cart: newCart
}
case REMOVE_FROM_CART:
const cart = [...state.cart]
const updatedCart = cart.filter(item => item.id !== action.payload.id)
return {
...state,
cart: updatedCart
}
default:
return state
}
}
export default ShoppinReducer
我的“購物車”組件如下:
import React, { Component } from "react"
import { Card, CardBody, CardHeader, CardTitle, Row, Col } from "reactstrap"
import PanelHeader from "components/PanelHeader/PanelHeader.js"
import { connect } from "react-redux";
import { removeCart} from "../redux/actions";
class Cart extends Component {
removeFromCart = (product) => {
const cartProducts = this.props.cart
const updatedCartProducts = cartProducts.filter(item => item.id !== product.id);
}
render () {
const cartProducts = this.props.cart
return (
<>
<PanelHeader size="sm" />
<div className="content">
<Row>
<Col xs={12}>
<Card>
<CardHeader>
<CardTitle tag="h4">Products List</CardTitle>
</CardHeader>
<CardBody>
<table class="table table-striped table-hover">
<thead>
<tr>
<th scope="col"><strong>#</strong></th>
<th scope="col"><strong>Name</strong></th>
<th scope="col"><strong>Code Item</strong></th>
<th scope="col"><strong>Quantity</strong></th>
<th scope="col"><strong>Price Total</strong></th>
</tr>
</thead>
<tbody>
{cartProducts.length > 0 && cartProducts.map((cartProduct, index) => (
<tr key={cartProduct.id}>
<th scope="row">{index 1}</th>
<td>{cartProduct.title}</td>
<td>{cartProduct.code}</td>
<td>{cartProduct.quantity}</td>
<td>{cartProduct.price}</td>
<td><button onClick ={() => this.props.removeCart(cartProduct)} className="btn btn-danger cart-button px-4">Remove</button></td>
</tr>))}
</tbody>
</table>
</CardBody>
</Card>
</Col>
</Row>
</div>
</>
)
}
}
const mapStateToProps = (state)=> {
return {
cart: state.cart
}
}
const mapDispatchToProps = (dispatch) => {
return {
removeCart: (product) => {dispatch(removeCart(product))}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Cart);
記住“addToCart”按鈕位于其他組件中,但是,我發布了“Cart”組件以顯示“Cart”的結構如何!先感謝您!
uj5u.com熱心網友回復:
在將任何商品推送到您的購物車之前,您需要檢查購物車中是否已經存在該商品,如果存在,您應該更新數量。您可以將ADD_TO_CART減速器中的案例重寫為如下所示:
const initialState = {
cart: [],
}
const ShoppinReducer = (state = initialState, action) => {
switch (action.type) {
case ADD_TO_CART:
let newCart = [...state.cart]
let itemIndex = state.cart.findIndex(obj=>obj.id===action.payload.id)
let currItem = state.cart[itemIndex]
if(currItem){
currItem.quantity = parseInt(currItem.quantity) 1
state.cart[itemIndex] = currItem
newCart = [...state.cart]
}
else{
newCart = newCart.concat(action.payload)
}
return {
cart: newCart
}
case REMOVE_FROM_CART:
const cart = [...state.cart]
const updatedCart = cart.filter(item => item.id !== action.payload.id)
return {
...state,
cart: updatedCart
}
default:
return state
}
}
uj5u.com熱心網友回復:
我希望我能正確理解你的問題。我假設你的購物車狀態是這樣的
cart: [
{itemId: '1', quantity: 1, price: 100, ...},
{itemId: '2', quantity: 1, price: 200, ...}
]
問題是您現有的 addToCart 操作只會將一個專案推送到陣列的末尾,而不檢查這是否是購物車中已經存在的專案。最終購物車最終像
cart: [
{itemId: '1', quantity: 1, price: 100, ...},
{itemId: '2', quantity: 1, price: 200, ...},
{itemId: '1', quantity: 1, price: 100, ...}
]
因此,您需要檢查是添加新專案還是現有專案,如果是現有專案,則需要更新現有專案數量而不是將其推送到陣列。
uj5u.com熱心網友回復:
您可以在ADD_TO_CART執行操作時檢查該專案是否已經在串列中。它可能是這樣的
const alreadyInList = state.cart.find(item => item.id === action.payload.id);
let newCart;
if (alreadyInList) { // increments quantity if item already in list
newCart = state.cart.map(item => {
if (item.id === action.payload.id) {
return {..item, quantity: item.quantity 1};
} else {
return item;
}
});
} else { // adds item to the end if it's not already in the list
newCart = [...state.cart, payload.action];
}
return {..state, cart: newCart};
但是,JavaScript Array 不是適合此類操作的資料結構。如果您使用的物件的鍵是產品 ID,而值是產品本身,那就更好了。然后您就可以檢查某個專案是否已經存在并更有效地更新它。
旁注:
在通過串列映射之前檢查cartProducts的長度
{cartProducts.length > 0 && cartProducts.map((cartProduct, index) => (...
你不需要這樣做,就cartProducts.map((cartProduct, index) => (...足夠了。
此外,您可以查看 react hooks 和 redux toolkit。這兩者都有助于減少樣板。
uj5u.com熱心網友回復:
正如@spiritWalker 所說,您必須在減速器中實作該邏輯。我給你舉個例子:
case ADD_TO_CART:
const newCart = [...state.cart]
const index = newCart.findIndex((item) => item.id == action.payload.id)
// If index is -1, no similar items were found so we
// add the item to the cart.
// Otherwise, the index of the item is returned and we use
// it to update the quantity property of the existing item.
if (index == -1) {
newCart.push(action.payload)
} else {
newCart[index].quantity
}
return {
...state,
cart: newCart
}
另外,我建議您嘗試使用Redux Toolkit Package,它從 Redux 中抽象了很多邏輯和樣板,絕對可以使您的代碼更精簡、更輕松。
快樂編碼!
uj5u.com熱心網友回復:
最終,以下代碼作業正常。我發布它以防萬一其他人需要它以供將來參考!
import { ADD_TO_CART } from './constants'
import { REMOVE_FROM_CART } from './constants'
// import { ADD_QUANTITY} from './constants'
// import { SUB_QUANTITY} from './constants'
// import { EMPTY_CART} from './constants'
const initialState = {
cart: [],
}
const ShoppinReducer = (state = initialState, action) => {
switch (action.type) {
case ADD_TO_CART:
let newCart = [...state.cart]
let itemIndex = state.cart.findIndex(obj=>obj.id===action.payload.id)
let currItem = state.cart[itemIndex]
if(currItem){
currItem.quantity = parseInt(currItem.quantity) 1
state.cart[itemIndex] = currItem
newCart = [...state.cart]
}
else {
newCart = newCart.concat(action.payload)
}
return {
cart: newCart
}
case REMOVE_FROM_CART:
const cart = [...state.cart]
const updatedCart = cart.filter(item => item.id !== action.payload.id)
return {
...state,
cart: updatedCart
}
default:
return state
}
}
export default ShoppinReducer
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/338463.html
標籤:javascript 反应 还原
