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

ReactJS如何按颜色、尺码等属性筛选统计商品对应库存数量

React商品SKU库存筛选功能实现方案

原有问题

  • 选项重复:直接遍历全量SKU渲染颜色/尺码选项,未做去重处理,同个属性值会多次展示
  • 逻辑错误:仅用单个库存值作为状态,且颜色、尺码单选框共用相同name属性,无法同时选中两个属性,也没有动态计算库存的逻辑

修复后完整代码

import React, { useState, useMemo } from "react";

export default function ControlledRadios() {
  const [selectedColor, setSelectedColor] = useState("");
  const [selectedSize, setSelectedSize] = useState("");

  const data = [
    {
      id: 1,
      name: "Product A",
      attributes: [
        { id: 1, color: "Red", size: "Small", qty: 200 },
        { id: 2, color: "Red", size: "Medium", qty: 100 },
        { id: 3, color: "Red", size: "Large", qty: 300 },
        { id: 4, color: "Yellow", size: "Small", qty: 200 },
        { id: 5, color: "Yellow", size: "Medium", qty: 100 },
        { id: 6, color: "Yellow", size: "Large", qty: 300 },
      ],
    },
  ];

  const skuList = data[0]?.attributes || [];
  // 去重得到颜色、尺码选项
  const colorOptions = [...new Set(skuList.map(item => item.color))];
  const sizeOptions = [...new Set(skuList.map(item => item.size))];

  // 动态计算库存
  const totalQty = useMemo(() => {
    if (!skuList.length) return 0;
    // 两个属性都选中,精准匹配
    if (selectedColor && selectedSize) {
      const matchedSku = skuList.find(
        sku => sku.color === selectedColor && sku.size === selectedSize
      );
      return matchedSku ? matchedSku.qty : 0;
    }
    // 仅选中颜色,求和
    if (selectedColor) {
      return skuList.reduce(
        (sum, sku) => sku.color === selectedColor ? sum + sku.qty : sum,
        0
      );
    }
    // 仅选中尺码,求和
    if (selectedSize) {
      return skuList.reduce(
        (sum, sku) => sku.size === selectedSize ? sum + sku.qty : sum,
        0
      );
    }
    return 0;
  }, [selectedColor, selectedSize, skuList]);

  return (
    <>
      <h1>Quantity: {totalQty}</h1>
      <fieldset>
        <h3>Color:</h3>
        {colorOptions.map(color => (
          <label key={color}>
            <input
              type="radio"
              name="color"
              value={color}
              checked={selectedColor === color}
              onChange={(e) => setSelectedColor(e.target.value)}
            />
            {color}
          </label>
          <br />
        ))}
        <h3>Size:</h3>
        {sizeOptions.map(size => (
          <label key={size}>
            <input
              type="radio"
              name="size"
              value={size}
              checked={selectedSize === size}
              onChange={(e) => setSelectedSize(e.target.value)}
            />
            {size}
          </label>
          <br />
        ))}
      </fieldset>
    </>
  );
}

核心改动说明

  • 新增selectedColor、selectedSize两个状态分别存储选中的属性值,单选框拆分两组不同name,支持同时选中颜色和尺码
  • 提前对颜色、尺码属性值做去重,每个属性仅展示一次选项
  • 新增动态库存计算逻辑:
    • 同时选中两个属性时,匹配对应SKU返回精准库存
    • 仅选中单个属性时,累加所有匹配该属性的SKU库存总和
    • 未选中任何属性时返回0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 01:24:03