在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
相关产品推荐
相关产品推荐

