redux 如何删除数组中有2个id的项,id为product,id为product detail

agxfikkp  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(126)

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
qlckcl4x

qlckcl4x1#

您应该将两个id(productId和productDetailId)都传递给removeItem reducer函数。

removeItem: (state, action) => {
        const {productId, productDetailId} = action.payload;
        const selectedProduct = state.cart.find((item) => item.id === productId);
        if(Array.isArray(selectedProduct?.product_details)) {
          selectedProduct.product_details = selectedProduct.product_details.filter(item => item.id !== productDetailId);
        } 
    },

基本上,我们正在做的是:
1.查找具有给定产品ID的产品
1.在选定(找到)的产品中,删除产品详细信息ID。
要调用,请调用以下命令:

dispatch(removeItem({
  productId: "yyy",
  productDetailId: "zzz"
}))

希望这样能解决问题。
谢谢

相关问题