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

如何为点击的特定按钮添加Loader?电商网站按钮加载问题

解决单个按钮点击后所有按钮显示加载状态的问题

问题根源在于你使用了一个全局的loader状态变量控制所有按钮的显示内容,调用setLoader(oval)时所有按钮会同步切换成加载状态。要实现仅被点击的按钮显示加载效果,需要为每个商品单独维护加载状态,而非使用单个变量。

修改方案

  1. 将全局loader状态替换为对象,跟踪每个商品ID的加载状态
  2. 添加购物车请求时,仅标记当前点击的商品为加载中
  3. 请求完成后(成功/失败),取消该商品的加载状态

修改后的完整代码

"use client";

const Products = () => {
  const oval = (
    // 你的加载器组件,示例用文字占位
    <span className="loader">Loading...</span>
  );
  const dispatch = useDispatch();
  const [products, setProducts] = useState<IProducts>();
  // 用对象跟踪每个商品的加载状态,键为商品ID,值为是否加载中
  const [loadingIds, setLoadingIds] = useState<Record<string, boolean>>({});

  useLayoutEffect(() => {
    // 获取商品列表的逻辑
  }, []);

  const addToDatabase = async (product: IProducts) => {
    const productId = product.id;
    // 标记当前商品为加载中
    setLoadingIds(prev => ({ ...prev, [productId]: true }));
    try {
      const res = await axios.post("/api/cart", { product });
      if (res.status === 200) {
        dispatch(addProduct(product));
      } else {
        alert("Something went wrong");
      }
    } catch (error) {
      alert("INTERNAL SERVER ERROR");
      console.log(error);
    } finally {
      // 无论请求结果如何,取消当前商品的加载状态
      setLoadingIds(prev => ({ ...prev, [productId]: false }));
    }
  };

  return (
    <>
      <div className="container">
        <div>
          {products &&
            products.map((product: IProducts) => (
              <div key={product.id}>
                <Image
                  src={product.image}
                  width={100}
                  height={100}
                  alt={product.title}
                />
                <h1>{product.title}</h1>
                <p>${product.price}</p>
                <button
                  id={`product-${product.id}`}
                  onClick={() => addToDatabase(product)}
                  {/* 加载时禁用按钮,防止重复点击 */}
                  disabled={loadingIds[product.id]}
                >
                  {/* 根据当前商品的加载状态显示对应内容 */}
                  {loadingIds[product.id] ? oval : "ADD TO CART"}
                </button>
              </div>
            ))}
        </div>
      </div>
    </>
  );
};

export default Products;

关键说明

  • loadingIds对象:通过商品ID作为键,精准控制单个商品按钮的加载状态,避免全局状态干扰
  • finally块:确保请求结束后一定会取消加载状态,防止按钮一直处于加载态
  • disabled属性:可选添加,避免用户在加载过程中重复点击同一按钮,减少无效请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:37:38