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

在React中实现两组单选按钮的选中总价计算方案问询

问题场景

现有商品数据如下:

const data = [
    {
      id: 1,
      category: "category1",
      name: "N/A",
      price: 0,
    },
    {
      id: 2,
      category: "category1",
      name: "Cheese",
      price: 220,
    },
    {
      id: 3,
      category: "category2",
      name: "Eggs",
      price: 420,
    },
    {
      id: 4,
      category: "category2",
      name: "Bananas",
      price: 515,
    }
]

通过RadiosBlock组件按分类渲染单选按钮组,每个分类仅能选中一项:

<form>
  <RadiosBlock
    items={data}
    category="category1"
    onSelectHandler={selectionHandler}
  >              
  </RadiosBlock>
  <RadiosBlock
    items={data}
    category="category2"
    onSelectHandler={selectionHandler}
  >              
  </RadiosBlock>
  <h2>Your order:</h2>
    Total: £
    {selections.price}
</form>

RadiosBlock内部筛选分类并渲染RadioItem的逻辑如下:

const categoryFilter = props.items.filter(
  (c) => c.category === props.category
);

<ul className="items-block__inner">
      {categoryFilter.map((item) => {
        return (
          <RadioItem
            isChecked={selectedItem.id === item.id}
            key={item.id}
            itemName={item.name}
            itemPrice={item.price}
            onClick={() => clickHandler(item)}
          />
        );
      })}
</ul>

需求是展示所有选中项的总价,计划用state维护选中项数组,但需要确保每个分类在数组中仅存在一个选中项,以下是可行的技术解决方案:


解决方案1:用对象存储选中项(推荐)

放弃数组,改用对象维护选中项,以分类名作为键、选中的商品对象作为值,天然保证每个分类只有一个选中项,逻辑更简洁:

1. 初始化状态

const [selectedItems, setSelectedItems] = useState({});

初始为空对象,后续每个分类的选中项会被存入对应键下。

2. 实现选择处理函数

用户点击单选按钮时,直接覆盖对应分类的已有选中项:

const selectionHandler = (selectedItem) => {
  setSelectedItems(prevState => ({
    ...prevState, // 保留其他分类的选中状态
    [selectedItem.category]: selectedItem // 更新当前分类的选中项
  }));
};

3. 计算总价

提取对象中的所有商品值,累加价格:

const totalPrice = Object.values(selectedItems).reduce((sum, item) => sum + item.price, 0);

在模板中直接使用totalPrice即可:

<h2>Your order:</h2>
Total: £{totalPrice}

4. 调整RadioItem的选中状态判断

把selectedItems作为props传入RadiosBlock,修改isChecked的判断逻辑:

isChecked={props.selectedItems[props.category]?.id === item.id}

解决方案2:维护数组时自动替换同分类项

如果坚持用数组存储选中项,可以在更新状态时先过滤掉当前分类的旧项,再添加新选中项:

1. 初始化状态

const [selectedItems, setSelectedItems] = useState([]);

2. 实现选择处理函数

const selectionHandler = (selectedItem) => {
  setSelectedItems(prevState => {
    // 过滤掉当前分类已存在的选中项
    const filteredItems = prevState.filter(item => item.category !== selectedItem.category);
    // 添加新选中项,返回新数组
    return [...filteredItems, selectedItem];
  });
};

3. 计算总价

直接对数组中的商品价格累加:

const totalPrice = selectedItems.reduce((sum, item) => sum + item.price, 0);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 22:15:37