function ProductCard ({image, name, stats, id}){
let dispatch = useDispatch()
let quantity = 1
return (
<>
<div className = "product-card">
<div className = "product-image-wrapper">
<img src = {image} alt = "" />
</div>
<div className = "image-metadata">
<div className = "data-wrapper">
<div className = "product-details">
<div className = "product-category">{stats.category}</div>
<div className = "product-name">{name}</div>
</div>
<div className = "action-btn-wrapper">
<div className = "add-to-cart" onClick = {()=>{
dispatch(addToCart({name,image,stats,id,quantity}))
}
}>
<img src = {addToCartIcon} alt = "" />
</div>
</div>
</div>
</div>
</div>
</>
)
}
import React, { useEffect } from "react";
import Header from "../components/header";
import Footer from "../components/footer";
import Checkout from "../components/checkout";
import { useSelector } from "react-redux";
function Cart (){
let cartCount = useSelector(state => state.cart.cart)
useEffect(()=>{
document.title = `TRAX- Cart(${cartCount.length} Items)`
},[cartCount])
return (
<>
<Header/>
<Checkout/>
<Footer/>
</>
)
}
export default Cart;
import React from "react";
import cartImage from '../assets/website-icons/9026048_shopping_cart_simple_icon.svg'
import productImage from '../assets/featured/chair-model.jpg'
import arabicImage from '../assets/featured/arabic-model.jpg'
import { useSelector } from "react-redux";
import CartItem from "../widgets/cartItem";
function Checkout(){
let cartCount = useSelector(state => state.cart.cart)
return (
<div className = "cart-wrapper">
<div className = "cart-page-icon">
<div className = "icon-container">
<img src= {cartImage} alt = "Shopping Cart Icon" />
{/* CART */}
</div>
</div>
<div className = "mini-slogan-wrapper">
Shop for upto $200 to enjoy<span>FREE SHIPPING</span>.
</div>
<div className = "cart-table-content">
<div className = "cart-table">
<div className = "table-cell header-cell">
<div className = "table-col-1">Product</div>
<div className = "table-col-2">Quantity</div>
<div className = "table-col-3">Price</div>
<div className = "table-col-4">Subtotal</div>
</div>
{
cartCount.map(({name,image,stats,id,quantity}) => {
return <CartItem id = {id} productImage = {image} quantity = {quantity} productStats = {{category : stats.category, color : stats.color}} productName = {name}/>
})
}
{/* <div className = "table-cell">
<div className = "table-col-1">
<div className = "product-entry">
<div className = "product-image">
<img src = {productImage} alt = "" />
</div>
<div className = "product-description">
<div className = "product-name">Sunny T-Shirt Merch By Zomato</div>
<div className = "product-extras">Color: Red, Size : XL, Fabric : Cotton</div>
<div className = "product-remove-btn">Remove</div>
</div>
</div>
</div>
<div className = "table-col-2">
<div className = "quantity-adjuster">
<div className = "decrementor">
<img src = {decrementor} alt = "" />
</div>
<div className = "quantity-value">1</div>
<div className = "incrementor">
<img src = {incrementor} alt = "" />
</div>
</div>
</div>
<div className = "table-col-3">$300</div>
<div className = "table-col-4">$300</div>
</div>
<div className = "table-cell">
<div className = "table-col-1">
<div className = "product-entry">
<div className = "product-image">
<img src = {arabicImage} alt = "" />
</div>
<div className = "product-description">
<div className = "product-name">Arabic Scarf - Embroidery Print</div>
<div className = "product-extras">Color: Mehroon, Size : Standard, Fabric : Linen</div>
<div className = "product-remove-btn">Remove</div>
</div>
</div>
</div>
<div className = "table-col-2">
<div className = "quantity-adjuster">
<div className = "decrementor">
<img src = {decrementor} alt = "" />
</div>
<div className = "quantity-value">1</div>
<div className = "incrementor">
<img src = {incrementor} alt = "" />
</div>
</div>
</div>
<div className = "table-col-3">$120</div>
<div className = "table-col-4">$120</div>
</div> */}
</div>
<div className = "checkout-container">
<div className = "checkout-heading">
Cart Summary
</div>
<div className = "selection-group">
<div className = "selection-option">
<div className = "selection-indicator-wrapper">
<div className = "selection-ball"></div>
</div>
<div className = "selection-value">Regular Shipping</div>
<div className = "selection-cost">$12.00</div>
</div>
<div className = "selection-option">
<div className = "selection-indicator-wrapper">
<div className = "selection-balls"></div>
</div>
<div className = "selection-value">Express Shipping</div>
<div className = "selection-cost">20.00</div>
</div>
</div>
<div className = "checkout-secondary-row" id = "checkout-subtotal">
<div className = "heading-secondary-row">Subtotal</div>
<div className = "cost-secondary-row">$420</div>
</div>
<div className = "checkout-secondary-row" id = "checkout-tax">
<div className = "heading-secondary-row">Tax</div>
<div className = "cost-secondary-row">$10</div>
</div>
<div className = "checkout-total" id = "checkout-total" >
<div className = "heading-total">Total</div>
<div className = "cost-total">$430</div>
</div>
<div className = "checkout-btn">Checkout</div>
</div>
</div>
</div>
)
}
export default Checkout;
import React from "react";
import decrementor from '../assets/website-icons/decrementor.svg'
import incrementor from '../assets/website-icons/incrementor.svg'
import { useDispatch } from "react-redux";
import { removeFromCart,incrementQty,decrementQty } from "../state-manager/Slices/cartSlice";
function CartItem ({productImage,productName, productStats,id,quantity}){
let dispatch = useDispatch()
return (
<div className = "table-cell">
<div className = "table-col-1">
<div className = "product-entry">
<div className = "product-image">
<img src = {productImage} alt = "" />
</div>
<div className = "product-description">
<div className = "product-name">Sunny T-Shirt Merch By Zomato</div>
<div className = "product-extras">Color:{productStats.color}, Size : XL, Fabric : Cotton</div>
<div className = "product-remove-btn" onClick = {()=>{
dispatch(removeFromCart({productImage,productName,productStats,id}))
}}>Remove</div>
</div>
</div>
</div>
<div className = "table-col-2">
<div className = "quantity-adjuster">
<div className = "decrementor" onClick = {()=>{
dispatch(decrementQty({id}))
}}>
<img src = {decrementor} alt = "" />
</div>
<div className = "quantity-value">{quantity}</div>
<div className = "incrementor" onClick = {()=>{
dispatch(incrementQty({id}))
}}>
<img src = {incrementor} alt = "" />
</div>
</div>
</div>
<div className = "table-col-3">${300}</div>
<div className = "table-col-4">${quantity * 300}</div>
</div>
)
}
export default CartItem;
import { createSlice } from "@reduxjs/toolkit"
let CartSlice = createSlice({
name : 'Cart',
initialState : {
cart : [],
checkoutTotal : 0
},
reducers : {
addToCart : (state,action)=>{
if (state.cart.length < 1){
state.cart = [...state.cart, action.payload]
}else {
state.cart.map(item => {
if (item.id == action.payload.id){
item.quantity++;
}else {
state.cart = [...state.cart, action.payload]
}
})
}
},
removeFromCart : (state,action)=>{
state.cart.map((item, index, cartItemArray) =>{
if (item.id == action.payload.id){
let rar = cartItemArray.splice(index,1)
console.info(rar)
}
})
},
incrementQty : (state,action)=>{
state.cart.map(item =>{
console.info(action.payload)
if (item.id == action.payload.id){
item.quantity = item.quantity + 1
}
})
},
decrementQty : (state,action)=>{
state.cart.map(item =>{
if (item.id == action.payload.id){
if (item.quantity > 0){
item.quantity = item.quantity - 1
}else {
console.info('its already nulled out')
}
}
})
}
}
})
export default CartSlice.reducer
export const {addToCart,removeFromCart, incrementQty,decrementQty} = CartSlice.actions
Я использую Redux для управления состоянием, всякий раз, когда я добавляю в корзину, при третьем щелчке мыши количество корзин начинает удваиваться, например, с 2 до 4, с 4 до 6 и т. д., я много пробовал, но не могу обернуть моя голова вокруг этого. Пожалуйста, дайте мне знать, что я делаю неправильно?
🤔 А знаете ли вы, что...
JavaScript был первоначально создан для улучшения интерактивности веб-страниц.
Это происходит потому, что вы перебираете все товары в корзине и для каждого товара добавляете весь cart
в cart
, здесь, в else
:
state.cart.map(item => {
if (item.id == action.payload.id){
item.quantity++;
}else {
state.cart = [...state.cart, action.payload]
}
})
Вместо этого вам нужно просто обновить существующий товар, указав новое количество. Что-то вроде этого:
const existing = state.cart.find(item => item.id === action.payload.id);
if (existing) {
existing.quantity ++;
} else {
state.cart.push(action.payload);
}
Я не могу протестировать код, но надеюсь, что он поможет вам выявить проблему.
Пожалуйста, дайте мне знать, если это поможет.