React映射列表项如何实现独立的Count状态控制
解决列表项共享数量状态的问题
你现在的问题根源是所有列表项共用了同一个count状态,所以操作一个会影响全部。要让每个项的数量独立,有两种常用方案:
方案一:用对象存储每个项的数量状态
把每个食物的数量存在一个对象里,用食物的唯一ID作为键,这样就能精准控制单个项的数量:
- 初始化状态
const [quantities, setQuantities] = useState(() => { // 遍历列表,给每个食物初始数量设为1 return cartItemArr.reduce((acc, entry) => { acc[entry.foodId.id] = 1; // 这里假设foodId.id是食物的唯一标识 return acc; }, {}); });
- 修改增减函数
让函数接收食物ID作为参数,只更新对应项的数量:
const increment = (itemId) => { setQuantities(prev => ({ ...prev, [itemId]: prev[itemId] + 1 })); }; const decrement = (itemId) => { setQuantities(prev => ({ ...prev, [itemId]: prev[itemId] > 1 ? prev[itemId] - 1 : 1 })); };
- 遍历渲染时绑定对应数据
{cartItemArr.map((entry: any) => { const itemId = entry.foodId.id; const count = quantities[itemId]; return ( <Flex key={itemId} // 用唯一ID当key,比index更稳定 w={'100%'} alignItems={'center'} justifyContent={'space-between'} > <Flex direction={'column'} justifyContent={'space-between'}> <Text fontWeight={600} fontSize={'14px'} textColor={'#000'}> {entry?.foodId.nameOfFood} </Text> <Text fontWeight={400} fontSize={'12px'} textColor={'#000'}> #{entry?.foodId.pricePerServing} </Text> </Flex> <HStack justify={'center'} w="109px" borderRadius={'40px'} py="8px" border={'1px solid #AA9F93'} > <AiOutlineMinus cursor={'pointer'} onClick={() => decrement(itemId)} className='cursor-pointer' /> <Text>{count}</Text> <AiOutlinePlus cursor={'pointer'} onClick={() => increment(itemId)} className='cursor-pointer' /> </HStack> </Flex> ) })}
方案二:抽离独立的列表项组件
把每个购物车项做成独立组件,让组件自己维护数量状态,代码更模块化:
- 创建CartItem组件
const CartItem = ({ entry }) => { const [count, setCount] = useState(1); const increment = () => { setCount(prev => prev + 1); }; const decrement = () => { setCount(prev => prev > 1 ? prev - 1 : 1); }; return ( <Flex key={entry.foodId.id} w={'100%'} alignItems={'center'} justifyContent={'space-between'} > <Flex direction={'column'} justifyContent={'space-between'}> <Text fontWeight={600} fontSize={'14px'} textColor={'#000'}> {entry?.foodId.nameOfFood} </Text> <Text fontWeight={400} fontSize={'12px'} textColor={'#000'}> #{entry?.foodId.pricePerServing} </Text> </Flex> <HStack justify={'center'} w="109px" borderRadius={'40px'} py="8px" border={'1px solid #AA9F93'} > <AiOutlineMinus cursor={'pointer'} onClick={decrement} className='cursor-pointer' /> <Text>{count}</Text> <AiOutlinePlus cursor={'pointer'} onClick={increment} className='cursor-pointer' /> </HStack> </Flex> ); };
- 父组件中使用该组件
{cartItemArr.map((entry: any) => ( <CartItem key={entry.foodId.id} entry={entry} /> ))}
两种方案都能实现每个项的数量独立变化,方案二更适合复杂场景,便于后续维护。
内容的提问来源于stack exchange,提问作者Olaoluwa Anigboro-Napoleon
相关产品推荐
相关产品推荐

