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

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>
  );
}

关键逻辑说明

  1. 状态提升:将子组件分散的count状态集中到父组件的travellerCounts对象,让父组件拥有全局控制权。
  2. 互斥递增:在handleIncrease中先重置所有计数器为0,再更新当前操作的计数器,确保同一时间只有一个计数器有非0值。
  3. 独立递减:递减操作仅修改当前计数器数值,不影响其他组件,符合常规交互预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 20:15:50