enter image description here
enter image description here
enter image description here
API数据
如何删除数组中的项目有2个id,id product和id product detail。当我点击要删除的产品时,redux选择数组1中的id来删除并删除所有产品详细信息。我想删除product detail而不是数组1中的产品
这是我的cartSlice.js在redux中
import { createSlice } from '@reduxjs/toolkit';
const cartSlice = createSlice({
name: 'cart',
initialState: {
cart: [],
},
reducers: {
addToCart: (state, action) => {
const itemInCart = state.cart.find((item) => item.id === action.payload.id && item.idProduct === action.payload.idProduct);
if (itemInCart) {
itemInCart.quantity++;
} else {
state.cart.push({ ...action.payload, quantity: 1 });
}
},
incrementQuantity: (state, action) => {
const item = state.cart.find((item) => item.id === action.payload);
item.quantity++;
},
decrementQuantity: (state, action) => {
const item = state.cart.find((item) => item.id === action.payload);
if (item.quantity === 1) {
item.quantity = 1
} else {
item.quantity--;
}
},
removeItem: (state, action) => {
const removeItem = state.cart.filter((item) =>
item.id !== action.payload
);
state.cart = removeItem;
},
},
});
export const cartReducer = cartSlice.reducer;
export const {
addToCart,
incrementQuantity,
decrementQuantity,
removeItem,
} = cartSlice.actions;
SingleProduct.js
import { useDispatch } from 'react-redux';
import { useSelector } from 'react-redux';
import { addToCart } from './redux/cartSlice';
function SingleProduct() {
const [index, setIndex] = useState(1);
const [product, setProduct] = useState([]);
const [productDetail, setProductDetail] = useState()
// Set option product
const [id, setId] = useState(1)
const [idProduct, setIdProduct] = useState(1)
const [name, setName] = useState('')
const [price, setPrice] = useState(0);
const [image, setImage] = useState(undefined)
const [colorValue, setColorValue] = useState(undefined)
const [ramValue, setRamValue] = useState(undefined)
const [storageValue, setStorageValue] = useState(undefined)
const cart = useSelector((state) => state.cart)
console.log(cart)
const dispatch = useDispatch()
// const getTotalQuantity = () => {
// let total = 0
// cart.forEach(item => {
// total += item.quantity
// })
// return total
// }
// get path
const location = useLocation()
const productId = location.pathname.split('/')[2]
const path = location.pathname
console.log(productId, path)
//fetch api product
useEffect(() => {
fetch(`https://api-uit.herokuapp.com/api/iphone/${productId}`)
.then(res => res.json())
.then(data => {
setProduct(data);
setName(data.name)
setId(data.id)
setProductDetail(data.product_details)
var dataFirst = data.product_details[0]
var checkRam = dataFirst.ram !== undefined ? `${dataFirst.ram}` : undefined
setRamValue(checkRam)
setPrice(dataFirst.price)
setStorageValue(dataFirst.storage)
setImage(dataFirst.image)
setColorValue(dataFirst.color)
})
}, [productId])
const product_current = {
id: id,
idProduct: idProduct,
name: name,
image: image,
price: price,
color: colorValue,
ram: ramValue,
storage: storageValue
};
console.log(product_current)
//handle option
const findColor = (color) => {
setColorValue(color);
}
const findRam = (ram) => {
setRamValue(ram);
}
const findStorage = (storage) => {
setStorageValue(storage);
}
// console.log(productDetail)
// handle render when choose option
useLayoutEffect(() => {
var target = productDetail && productDetail.find(item => {
var ram = ramValue === undefined ? ramValue : `${ramValue}`;
return (
item.ram === ram &&
item.color === `${colorValue}` &&
item.storage === `${storageValue}`
)
})
// console.log(target)
var changeName = target !== undefined ? (target.name) : name;
var changeId = target !== undefined ? (target.id) : idProduct;
var changeImage = target !== undefined ? (target.image) : image;
var changePrice = target !== undefined ? (target.price) : price;
setIdProduct(changeId)
setName(changeName)
setImage(changeImage)
setPrice(changePrice)
// console.log(result);
}, [productDetail, ramValue, colorValue, storageValue, price, image, name, idProduct])
const getText = (html) => {
const doc = new DOMParser().parseFromString(html, "text/html")
return doc.body.textContent
}
const priceString = getText(price.toLocaleString().concat('đ'))
return (
<div className={cx('wrap')}>
<div className="grid wide">
<div className="wide row">
<div className="wide l-6 m-6 c-12" >
<img className={cx('img-product')} src={(image)} alt={product.name} />
</div>
<div className="wide l-6 m-6 c-12">
<div className={cx("wrap-heading")}>
<div className={cx('heading')}>{name}</div>
<div className={cx('separate')}></div>
<div className={cx('price')}>{priceString}</div>
{/* Check product have storage */}
{product.option && product.option.map((option, idx) =>
<div key={idx}>
{(option.key === "storage" ?
<div className={cx('wrap-storage')}>
<div className={cx('storage-heading')}>Chọn {option.key}</div>
<div className={cx('wrap-option')}>
{option.value.map((value, idx) =>
<div className={cx('option', `${value === storageValue ? "active" : ""}`)}
key={idx}
value={value}
onClick={() => findStorage(value)}
>
{value}
</div>
)}
</div>
</div> : <></>)}
</div>
)}
{/* Check product have ram */}
{product.option && product.option.map((option, idx) =>
<div key={idx}>
{(option.key === "ram" ?
<div className={cx('wrap-storage')}>
<div className={cx('storage-heading')}>Chọn {option.key}</div>
<div className={cx('wrap-option')}>
{option.value.map((value, idx) =>
<div className={cx('option', `${value === ramValue ? "active" : ""}`)}
key={idx}
value={value}
onClick={() => findRam(value)}
>
{value}
</div>
)}
</div>
</div> : <></>)}
</div>
)}
{/* Check product have color */}
{product.option && product.option.map((option, idx) =>
<div key={idx}>
{(option.key === "color" ?
<div className={cx('wrap-color')}>
<div className={cx('heading-color')}>Chọn {option.key}</div>
<div className={cx('option-color')}>
{option.value.map((value, idx) =>
<div className={cx('space', `${value === colorValue ? "active" : ""}`)}
key={idx}
value={value}
onClick={() => findColor(value)}
>
<div className={cx('radio-color')} style={{ backgroundColor: value }}></div>
</div>
)}
</div>
</div> : <></>)}
</div>
)}
<div className={cx('wrap-buy')}>
<div className={cx('box-buy')}>
<div className={cx('buy-cash')}>MUA NGAY</div>
</div>
<div className={cx('box-buy')}>
<div className={cx('add-to-list')}
onClick={() => dispatch(addToCart(product_current))}
>THÊM VÀO GIỎ HÀNG</div>
</div>
</div>
</div>
</div>
)
}
export default SingleProduct
这是我的网站
import React, { useState } from 'react'
import classNames from "classnames/bind";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useSelector } from 'react-redux';
import { useDispatch } from 'react-redux'
import { faXmark, faBagShopping } from "@fortawesome/free-solid-svg-icons";
import styles from './Cart.module.scss'
import { removeItem } from 'src/pages/SingleProduct/redux/cartSlice'
const cx = classNames.bind(styles)
function Cart() {
const dispatch = useDispatch()
const [showCart, setShowCart] = useState(false)
// toggle cart
const ToggleCart = () => {
setShowCart(!showCart)
}
const show = showCart ? 'toggle-cart' : ''
const cart = useSelector((state) => state.cart)
// console.log(cart)
// Tính tổng
const getTotal = () => {
let totalQuantity = 0
let totalPrice = 0
cart.forEach(item => {
totalQuantity += item.quantity
totalPrice += item.price * item.quantity
})
return { totalPrice, totalQuantity }
}
const getText = (html) => {
const doc = new DOMParser().parseFromString(html, "text/html")
return doc.body.textContent
}
const totalPrice = getTotal().totalPrice
const priceTotalString = getText(totalPrice.toLocaleString().concat('đ'))
return (
<>
<div className={cx('wrap-cart')}>
<FontAwesomeIcon className={cx('icon')} icon={faBagShopping} onClick={ToggleCart} />
<p>{getTotal().totalQuantity || 0}</p>
</div>
{show && <div className={cx('wrap-modal')} onClick={ToggleCart}>
</div>}
<div className={cx('cart', show)}>
<FontAwesomeIcon icon={faXmark} className={cx('icon-mark-cart')} onClick={ToggleCart} />
<div className={cx('height-cart')}>
{cart.map((product, idx) =>
<div className={cx('product-cart')} key={idx}>
<img className={cx('cart-img')} src={product.image} alt="" />
<div className={cx('wrapper-cart')}>
<div className={cx('name-cart')}>{product.name}</div>
<p className={cx('price-cart')}>{product.quantity} x {getText(product.price.toLocaleString().concat('đ'))}</p>
</div>
<div
className={cx('cartItem__removeButton')}
onClick={() => dispatch(removeItem(product.id && product.idProduc))}>
x
</div>
</div>
)}
</div>
<div className={cx('footer-cart')}>
<div className={cx('wrap-total')}>
<p>Tạm tính: </p>
<p>{priceTotalString}</p>
</div>
<div className={cx('wrap-pay')}>
<div className={cx('cart-buy')}>MUA NGAY</div>
</div>
</div>
</div>
</>
)
}
export default Cart
1条答案
按热度按时间qlckcl4x1#
您应该将两个id(productId和productDetailId)都传递给
removeItem
reducer函数。基本上,我们正在做的是:
1.查找具有给定产品ID的产品
1.在选定(找到)的产品中,删除产品详细信息ID。
要调用,请调用以下命令:
希望这样能解决问题。
谢谢