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

React循环中如何单独控制单个按钮的交互状态?

问题原因

你当前的代码使用了全局共享的状态addToCart和count,所有通过map渲染的按钮都绑定到这两个状态上。点击任意一个按钮时,会修改全局状态,导致所有按钮的文本同步切换,count也全局累加,这就是所有按钮同时响应的核心原因。

解决方案

要实现单个按钮独立交互,需要为每个商品维护单独的购物车状态,而非用全局状态统一控制。具体步骤如下:

  • 用对象类型的状态cartItems存储每个商品的购物车状态(键为商品唯一标识,值为商品的购物车信息)
  • 修改交互函数,接收商品标识作为参数,仅更新对应商品的状态
  • 全局商品总数通过计算cartItems的总和得到,无需单独维护状态
修改后的完整代码
import React, { useEffect, useState, useMemo } from "react";

function Women() {
  const [womenShoes, setWomenShoes] = useState([]);
  // 用对象存储每个商品的购物车状态,键为商品唯一标识
  const [cartItems, setCartItems] = useState({});

  // 针对单个商品切换添加/移除状态
  const toggleCartItem = (itemId) => {
    setCartItems(prevCart => {
      if (prevCart[itemId]) {
        // 已在购物车,移除该商品
        const newCart = {...prevCart};
        delete newCart[itemId];
        return newCart;
      } else {
        // 不在购物车,添加数量为1的商品
        return {...prevCart, [itemId]: { quantity: 1 }};
      }
    });
  };

  useEffect(() => {
    fetch("https://pacific-leaf-twig.glitch.me/women-shoes")
      .then((response) => response.json())
      .then((data) => setWomenShoes(data));
  }, []);

  // 计算购物车总商品数
  const totalItemCount = useMemo(() => {
    return Object.values(cartItems).reduce((total, item) => total + item.quantity, 0);
  }, [cartItems]);

  return (
    <div className="d-flex flex-wrap justify-content-center gap-5 mt-5">
      {womenShoes.map((shoe, index) => {
        // 优先用接口返回的商品id,无id则用index作为唯一标识
        const itemId = shoe.id || index;
        const isInCart = !!cartItems[itemId];
        
        return (
          <div key={itemId} className="card mt-5" style={{ width: "25rem" }}>
            <img src={shoe.img} className="card-img-top img-fluid" alt="A shoe" />
            <div className="card-body d-flex">
              <div>
                <h5 className="card-title">{shoe.name}</h5>
                <p className="card-text">{`Items Remaining ${shoe.itemsLeft}`}</p>
                <button 
                  onClick={() => toggleCartItem(itemId)} 
                  className="btn btn-primary"
                >
                  {isInCart ? "Remove from the Cart" : "Add to Cart"}
                </button>
              </div>
              <div className="mx-auto align-self-center">
                <h4>{`$ ${shoe.price}`}</h4>
              </div>
            </div>
          </div>
        );
      })}
      <div className="counter">{`Items: ${totalItemCount}`}</div>
    </div>
  );
}

export default Women;
关键改动说明
  • 用cartItems对象替代全局的addToCart和count,每个商品的购物车状态独立存储
  • toggleCartItem函数接收商品标识,仅修改对应商品的状态
  • 通过useMemo计算购物车总数量,避免重复计算
  • 按钮点击事件绑定带参数的函数,确保触发时能定位到具体商品

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 15:39:14