Как сделать проверку товара в корзине?

При клике на кнопку + товар добавляется в корзину. Если кликнуть еще раз, то он добавляется снова (скрин приложил). Я хочу, чтобы при добавлении одного и того же товара, он не дублировался в корзине. Не получается реализовать. Мои мысли такие: в блоке const onAddToCart = (obj) => { setCartItems([...cartItems, obj]); }; пройтись по массиву cartItems и сравнить cartItem.name c obj.name и если они не совпадают, то добавлять товар в корзину:

const onAddToCart = (obj) => {
cartItems.forEach(function(cartItem) {
if(cartItem.name != obj.name) {
 setCartItems([...cartItems, obj]);}
})
   


     function App() {
  const [items, setItems] = useState([]);
  const [cartItems, setCartItems] = useState([]);
  const [openCart, setOpenCart] = useState(false);

  useEffect(() => {
    fetch('https://636f5291f2ed5cb047daa480.mockapi.io/articles')
      .then((response) => {
        return response.json();
      })
      .then((json) => setItems(json));
  }, []);

  const onAddToCart = (obj) => {
    setCartItems([...cartItems, obj]);
  };

  return (
    <div className="wrapper">
      {openCart && <Cart onClose={() => setOpenCart(false)} cartItems={cartItems} />}
      <Header onClickCart={() => setOpenCart(true)} />
      <main>
        <div className="searchBlock">
          <h1>Все кроссовки</h1>
          <div className="searchItem">
            <img className="searchLogo" src="/img/search.svg" alt="search" />
            <input type="search" placeholder="Поиск..." />
          </div>
        </div>
        <div className="sneakers">
          {items.map((item) => (
            <Card
              name={item.name}
              price={item.price}
              image={item.imageUrl}
              addToCart={(obj) => onAddToCart(obj)}
            />
          ))}
        </div>
      </main>
    </div>
  );
}

Но эта теория не сработала. Прошу помочь, что делаю не так и в каком направлении двигаться?

Компонент Cart

import { IconContext } from 'react-icons';
import { MdRemoveCircle } from 'react-icons/md';
import { IoIosCloseCircleOutline } from 'react-icons/io';

const Cart = ({ onClose, cartItems }) => {
  return (
    <div className="overlay">
      <div className="drawer">
        <div className="drawer_header">
          <h2>Корзина</h2>
          <div className="closeCart" onClick={onClose}>
            <IoIosCloseCircleOutline size={21} />
          </div>
        </div>
        {cartItems.length > 0 ? (
          <div className="cartItems">
            {cartItems.map((obj) => (
              <div className="cartItem">
                <img width={70} height={70} src={obj.image} alt="Nike Blazer" />
                <div className="cartPrice">
                  <p>{obj.name}</p>
                  <b>{obj.price}</b>
                </div>
                <IconContext.Provider value={{ style: { verticalAlign: 'middle' } }}>
                  <MdRemoveCircle size={21} className="removeBtn" />
                </IconContext.Provider>
              </div>
            ))}
          </div>
        ) : (
          'Корзина пуста'
        )}
        <div className="totalPrice">
          <span>Итого:</span>
          <div className="line"></div>
          <b>21 498 руб.</b>
        </div>
        <button className="greenBtn">
          Оформить заказ <img src="/img/arrow.svg" alt="Arrow" />
        </button>
      </div>
    </div>
  );
};

export default Cart;

корзина


Ответы (1 шт):

Автор решения: SwaD

Ваша теория и размышление правильные.

Должно работать вот с такой проверкой:

const onAddToCart = (obj) => {
  if (!cartItems.some(item => item.name === obj.name)) {
    setCartItems([...cartItems, obj]);
  }
};

Бежим по текущему состоянию корзины методом some и если не найдется ни одного совпадения name, то будет выполнено добавление элемента в корзину

Возможно вы не правильно работали с массивом

→ Ссылка