reactjs 向从API获取的数组中的对象添加了新键值,并尝试切换键值,但未定义

2ekbmq32  于 2023-01-04  发布在  React
关注(0)|答案(1)|浏览(74)

基本上,我是从API获取产品,并将新键值isAdded添加到products数组内的对象,我使用foreach循环添加该键值,并成功添加,当我按下Add to cart按钮时我添加产品项目到我的<Cart />这也是工作正常,但唯一的事情我想做的是当该特定产品添加到购物车我想更改按钮的文本和样式,这意味着我想切换isAdded的值。但是当我单击按钮时,isAdded似乎未定义,其他数据正常,但我的键不正常。
BookProduct.js

import BookItems from "./BookItems";
import classes from "./book-item.module.css";
import { useEffect } from "react";

export default function BookProducts({ booksData }) {
    useEffect(() => {
        booksData.forEach((element) => {
            element.isAdded = false;
        });
    }, []);

    console.log(booksData); //isAdded key perfectly added in the object

    return (
        <div className="container">         
                {booksData.map((el) => {
                    return (
                        <BookItems
                            id={el.isbn13}
                            key={el.isbn13}
                            imageUrl={el.image}
                            price={Number(el.price.slice(1))}
                            title={el.title}
                            subtitle={el.subtitle}
                            link={el.link}
                            isAdded={el.isAdded}
                        />
                    );
                })}     
        </div>
    );
}

BookItems.js

import { useDispatch, useSelector } from "react-redux";
import Image from "next/image";
import Link from "next/link";
import classes from "./book-item.module.css";
import { cartStoreAction } from "../../store/cart-items";

export default function BookItems(props) {
    const { id, title, price, imageUrl, isAdded } = props;
    const dispatch = useDispatch();

    const addToCartHandler = () => {
        dispatch(
            cartStoreAction.addProduct({
                id,
                title,
                price,
                imageUrl,
                isAdded
            })
        );
        console.log(isAdded); //isAdded is undefined
    };

    return (
        <div className={classes.product__item}>
            <Link href={`/products/${id}`} className={classes.image_box}>
                <Image src={imageUrl} alt={title} className={classes.image} fill />
            </Link>
            <div className={classes.desc_box}>
                <Link href={`/products/${id}`}>
                    <h3>{title}</h3>
                </Link>
                <div className={classes.bottom}>
                    <p>${price}</p>
                    <button onClick={addToCartHandler}>
                        {isAdded ? 'Added' : 'Add to cart'}
                    </button>
                </div>
            </div>
        </div>
    );
}

cart-items.js

const cartItemSlice = createSlice({
    name: "cart",
    initialState: {
        items: [],
        totalQuantity: 0,
        totalAmount: 0,
    },
    reducers: {
        addProduct(state, action) {
            const newCartItems = action.payload; //items from dispatch object
            const existingItem = state.items.find((el) => el.id === newCartItems.id);                   
            state.totalQuantity++;
            if (!existingItem) {
                state.items.push({
                    id: newCartItems.id,
                    quantity: 1,
                    title: newCartItems.title,
                    price: newCartItems.price,
                    image: newCartItems.imageUrl,
                    totalPrice: newCartItems.price,     
                    isAdded: !newCartItems.isAdded,
                });
                !newCartItems.isAdded;
            } else {
                existingItem.quantity++;
                existingItem.totalPrice = existingItem.totalPrice + newCartItems.price;
            }
            state.totalAmount = state.items.reduce(
                (acc, index) => acc + Number(index.price) * Number(index.quantity),
                0
            );
        },      
    },
});
btqmn9zl

btqmn9zl1#

看起来你修改了错误的对象。不要修改传递的 prop 。我建议跳过在addProduct reducer函数中设置任何isAdded属性,并在BookItems组件中选择状态,以了解是否已根据项目ID将项目添加到购物车中。
购物车项目切片

const cartItemSlice = createSlice({
  name: "cart",
  initialState: {
    items: [],
    totalQuantity: 0,
    totalAmount: 0,
  },
  reducers: {
    addProduct(state, action) {
      const { payload } = action; // items from dispatch object
      const existingItem = state.items.find((el) => el.id === payload.id);
                
      if (!existingItem) {
        state.items.push({
          quantity: 1,
          ...payload,
          totalPrice: payload.price,
        });
      } else {
        existingItem.quantity++;
        existingItem.totalPrice += newCartItems.price;
        isAddedToCart();
      }

      state.totalQuantity++;
      state.totalAmount = state.items.reduce(
        (acc, index) => acc + Number(index.price) * Number(index.quantity),
        0
      );
    },
    removeProduct(state, action) {
      const removingItemId = action.payload;
      const alreadyAddedItem = state.items.find(
        (item) => item.id === removingItemId
      );
      
      if (alreadyAddedItem.quantity === 1) {
        state.items = state.items.filter((item) => item.id !== removingItemId);
      } else {
        alreadyAddedItem.quantity--;
        alreadyAddedItem.totalPrice -= alreadyAddedItem.price;
      }

      state.totalQuantity--;
      state.totalAmount = state.items.reduce(
        (acc, index) => acc + Number(index.price) * Number(index.quantity),
        0
      );
    },
  },
});

图书产品

export default function BookProducts({ booksData }) {
  return (
    <div className="container">
      {booksData.map((el) => (
        <BookItems
          id={el.isbn13}
          key={el.isbn13}
          image={el.image}
          price={Number(el.price.slice(1))}
          title={el.title}
        />
      ))}
    </div>
  );
}

书籍项目
从商店中选择购物车项目,并检查当前的BookItemsid属性是否与购物车项目数组中的元素匹配。

import { useDispatch, useSelector } from "react-redux";
...

export default function BookItems({ id, title, price, image }) {
  const dispatch = useDispatch();

  const cartItems = useSelector(state => state.cart.items);

  const isAdded = cartItems.some(item => item.id === id); // <-- compute here

  const addToCartHandler = () => {
    dispatch(cartStoreAction.addProduct({
      id,
      title,
      price,
      image,
    }));
  };

  return (
    <div className={classes.product__item}>
      <Link href={`/products/${id}`} className={classes.image_box}>
        <Image src={image} alt={title} className={classes.image} fill />
      </Link>
      <div className={classes.desc_box}>
        <Link href={`/products/${id}`}>
          <h3>{title}</h3>
        </Link>
        <div className={classes.bottom}>
          <p>${price}</p>
          <button onClick={addToCartHandler}>
            {isAdded ? 'Added' : 'Add to cart'}
          </button>
        </div>
      </div>
    </div>
  );
}

相关问题