You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS+Redux购物车页面开发问题:数量/重复/按钮切换

React + Redux购物车问题解决方案

问题1:无法获取商品数量

当前代码未维护商品数量字段,添加商品时未初始化数量值,购物车页面也未正确读取数量。

修改方案:

  1. 更新cartSlice,新增数量维护逻辑及修改数量的reducer:
const CartSlice = createSlice({
  name: "cart",
  initialState: [],
  reducers: {
    add(state, action) {
      // 检查商品是否已在购物车中
      const existingItem = state.find(item => item.id === action.payload.id);
      if (existingItem) {
        // 已存在则增加数量
        existingItem.quantity += 1;
      } else {
        // 不存在则新增,初始化数量为1
        state.push({...action.payload, quantity: 1});
      }
    },
    remove(state, action) {
      return state.filter((item) => item.id !== action.payload);
    },
    // 新增修改数量的reducer
    updateQuantity(state, action) {
      const {id, type} = action.payload;
      const item = state.find(item => item.id === id);
      if (item) {
        if (type === "increment") {
          item.quantity += 1;
        } else if (type === "decrement" && item.quantity > 1) {
          item.quantity -= 1;
        }
      }
    }
  },
});

// 导出新增的action
export const { add, remove, updateQuantity } = CartSlice.actions;
export default CartSlice.reducer;
  1. 修改购物车页面,实现数量显示及增减功能:
const Cart = () => {
  const [total, setTotal] = useState(0);
  const dispatch = useDispatch();
  const carts = useSelector((state) => state.cart);
  
  const handleRemove = (productId) => {
    dispatch(remove(productId));
  };

  const handleQuantityChange = (id, type) => {
    dispatch(updateQuantity({id, type}));
  };

  useEffect(() => {
    setTotal(
      carts.reduce(
        (acc, curr) => acc + Number(curr.price.toString().split(".")[0]) * curr.quantity,
        0
      )
    );
  }, [carts]);

  return (
    <>
      <div>
        {carts.map((product) => {
          return (
            <div className={style.product_cart} key={product.id}>
              <img
                src={product.image}
                alt="product_image"
                className={style.product_image}
              />
              <p className={style.product_title}>
                {product.title.substring(0, 18)}...
              </p>
              <p className={style.product_price}>
                ₹{product.price.toString().split(".")[0]}
              </p>

              <div className={style.product_quantity}>
                <button className="decrement" onClick={() => handleQuantityChange(product.id, "decrement")}>-</button>
                <p>{product.quantity}</p>
                <button className="increment" onClick={() => handleQuantityChange(product.id, "increment")}>+</button>
              </div>

              <button
                onClick={() => handleRemove(product.id)}
              >
                <AiFillDelete className={style.product_delete_icon} />
              </button>
            </div>
          );
        })}
      </div>

      <div className={style.cartItem_2}>
        <p className={style.product_total}>
          <span>Total :</span>
          &nbsp;
          <strong>₹{total}</strong>
        </p>
        <div className={style.cart_buyNow}>
          <Link to="/buyNow">
            <button className={style.buyNow}>
              <AiFillThunderbolt /> <span>Buy Now</span>
            </button>
          </Link>
        </div>
      </div>
    </>
  );
};

问题2:添加商品到购物车时出现重复

原因是原add reducer直接将商品推入数组,未判断商品是否已存在。上述修改后的cartSlice中,add reducer会先检查商品是否在购物车,存在则仅增加数量,不存在才新增条目,该问题已解决。

问题3:商品详情页点击“Add to cart”后按钮未切换为“go to cart”

需要在商品详情页中获取购物车状态,判断当前商品是否已在购物车内,根据状态切换按钮的文字与跳转逻辑。

修改方案:

const SingleProduct = () => {
  const dispatch = useDispatch();
  const { data: products } = useSelector((state) => state.product);
  const carts = useSelector((state) => state.cart);
  const { productId } = useParams();
  const product = products.find((product) => String(product.id) === productId);
  
  // 判断当前商品是否在购物车中
  const isInCart = carts.some(item => item.id === product.id);

  const handleAdd = (product) => {
    dispatch(add(product));
  };

  return (
    <section className={style.SingleProductSection}>
      <div className={style.btns}>
        {isInCart ? (
          <Link to="/cart">
            <button className={style.addToCart}>
              <FaCartPlus />
              <span>Go to cart</span>
            </button>
          </Link>
        ) : (
          <button
            className={style.addToCart}
            onClick={() => handleAdd(product)}
          >
            <FaCartPlus />
            <span>Add to cart</span>
          </button>
        )}
        <Link to="/buyNow">
          <button className={style.buyNow}>
            <AiFillThunderbolt /> <span>Buy Now</span>
          </button>
        </Link>
      </div>
    </section>
  );
};

内容的提问来源于stack exchange,提问作者sktsandeep1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 09:01:43