React多计数器组件开发:递增某一计数器时重置其余为0
实现计数器互斥重置功能(递增一个时其余清零)
你当前的四个计数器组件各自维护自身状态,父组件无法联动控制。要达成递增任意一个计数器时,其余三个自动重置为0的效果,核心是把计数器的状态从子组件提升到父组件统一管理,让父组件掌握所有计数器的数值,进而处理互斥逻辑。
步骤1:修改子组件NoTravellers
子组件不再自行维护count状态,改为从父组件接收count、onIncrease、onDecrease属性,专注于展示和触发操作:
function NoTravellers({ label, count, onIncrease, onDecrease }) { const reduceCount = () => { if (count === 0) return; onDecrease(); }; const increaseCount = () => { if (count >= 2) return; onIncrease(); }; return ( <div className="flex justify-around mb-8 w-1/3"> <div> <span className="font-semibold text-sm">{label}</span> </div> <div className="flex space-x-4 justify-center"> <MinusCircleIcon className="w-6 h-6 text-[#33C5B4]" onClick={reduceCount} /> <span className="text-base text-[#565656] font-semibold">{count}</span> <PlusCircleIcon className="w-6 h-6 text-[#33C5B4]" onClick={increaseCount} /> </div> </div> ); } export default NoTravellers;
步骤2:修改父组件,统一管理状态与互斥逻辑
在父组件中维护所有计数器的数值,实现递增时的互斥重置逻辑,递减时仅修改当前计数器数值:
import { useState } from 'react'; import NoTravellers from './NoTravellers'; function ParentComponent() { // 用对象存储各计数器数值,对应不同类型 const [travellerCounts, setTravellerCounts] = useState({ adults: 0, students: 0, seniors: 0, childrens: 0 }); // 递增逻辑:先重置所有计数器为0,再给当前类型加1 const handleIncrease = (type) => { setTravellerCounts(prev => { if (prev[type] >= 2) return prev; // 重置所有值为0,再更新当前类型的数值 const newCounts = Object.fromEntries( Object.keys(prev).map(key => [key, 0]) ); newCounts[type] = prev[type] + 1; return newCounts; }); // 可保留原chooseTravellers逻辑,比如映射类型到ID后调用 // const typeId = { adults:1, students:2, seniors:3, childrens:4 }[type]; // chooseTravellers(newCounts[type], typeId); }; // 递减逻辑:仅修改当前计数器的数值 const handleDecrease = (type) => { setTravellerCounts(prev => { if (prev[type] === 0) return prev; return { ...prev, [type]: prev[type] - 1 }; }); }; // 如需同步触发原chooseTravellers,可监听状态变化 // useEffect(() => { // const active = Object.entries(travellerCounts).find(([key, val]) => val > 0); // if (active) { // const [type, count] = active; // const typeId = { adults:1, students:2, seniors:3, childrens:4 }[type]; // chooseTravellers(count, typeId); // } // }, [travellerCounts]); return ( <div className="flex flex-col justify-center"> <div className="flex justify-around"> <NoTravellers label="Adults" count={travellerCounts.adults} onIncrease={() => handleIncrease('adults')} onDecrease={() => handleDecrease('adults')} /> <NoTravellers label="Students" count={travellerCounts.students} onIncrease={() => handleIncrease('students')} onDecrease={() => handleDecrease('students')} /> </div> <div className="flex justify-around"> <NoTravellers label="Seniors" count={travellerCounts.seniors} onIncrease={() => handleIncrease('seniors')} onDecrease={() => handleDecrease('seniors')} /> <NoTravellers label="Childrens" count={travellerCounts.childrens} onIncrease={() => handleIncrease('childrens')} onDecrease={() => handleDecrease('childrens')} /> </div> </div> ); }
关键逻辑说明
- 状态提升:将子组件分散的
count状态集中到父组件的travellerCounts对象,让父组件拥有全局控制权。 - 互斥递增:在
handleIncrease中先重置所有计数器为0,再更新当前操作的计数器,确保同一时间只有一个计数器有非0值。 - 独立递减:递减操作仅修改当前计数器数值,不影响其他组件,符合常规交互预期。
内容的提问来源于stack exchange,提问作者Atal Shrivastava
相关产品推荐
相关产品推荐

