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

React.js:子组件触发父组件状态变更时如何更新多个子组件

解决React同组按钮点击后禁用其他按钮的方案

嘿,我完全懂你这种被React组件通信绕晕的感觉——尤其是跨层级或者同组组件之间的交互,刚开始确实容易卡壳!针对你说的「同组按钮点击后启用/禁用其他同组按钮」的需求,咱们可以用状态提升的思路来解决,这也是React里处理这类兄弟组件通信最常用的方法之一,上手简单还不容易出错。

核心思路

把同组按钮的「激活状态」统一放在父组件中管理,子按钮只负责接收状态和触发点击事件——这样所有同组按钮的状态都由同一个源头控制,自然就能实现点击一个、其他同组按钮同步禁用/启用的效果。

具体代码实现

1. 父组件:管理分组状态和点击逻辑

import { useState } from 'react';

// 按钮分组组件
function ButtonGroup() {
  // 用对象存储不同分组的激活按钮ID,键是分组类型,值是当前激活的按钮ID
  const [activeButtons, setActiveButtons] = useState({});

  // 处理按钮点击的通用函数
  const handleButtonClick = (buttonId, groupType) => {
    setActiveButtons(prevState => {
      // 获取当前分组的激活按钮
      const currentActive = prevState[groupType];
      // 如果点击的是已激活的按钮,就取消激活;否则设置为当前按钮
      return {
        ...prevState,
        [groupType]: currentActive === buttonId ? null : buttonId
      };
    });
  };

  return (
    <div className="button-container">
      {/* TypeA分组 */}
      <div className="group">
        <h3>TypeA分组</h3>
        <GroupButton 
          id="typeA-btn1" 
          groupType="typeA" 
          isDisabled={activeButtons.typeA !== null && activeButtons.typeA !== "typeA-btn1"}
          onClick={() => handleButtonClick("typeA-btn1", "typeA")}
        />
        <GroupButton 
          id="typeA-btn2" 
          groupType="typeA" 
          isDisabled={activeButtons.typeA !== null && activeButtons.typeA !== "typeA-btn2"}
          onClick={() => handleButtonClick("typeA-btn2", "typeA")}
        />
      </div>

      {/* TypeB分组 */}
      <div className="group">
        <h3>TypeB分组</h3>
        <GroupButton 
          id="typeB-btn1" 
          groupType="typeB" 
          isDisabled={activeButtons.typeB !== null && activeButtons.typeB !== "typeB-btn1"}
          onClick={() => handleButtonClick("typeB-btn1", "typeB")}
        />
        <GroupButton 
          id="typeB-btn2" 
          groupType="typeB" 
          isDisabled={activeButtons.typeB !== null && activeButtons.typeB !== "typeB-btn2"}
          onClick={() => handleButtonClick("typeB-btn2", "typeB")}
        />
      </div>
    </div>
  );
}

2. 子组件:纯UI渲染的按钮

子组件不需要自己维护状态,只需要接收父组件传递的props,负责渲染按钮和触发点击事件即可:

// 单个组按钮组件
function GroupButton({ id, groupType, isDisabled, onClick }) {
  return (
    <button 
      style={{ 
        margin: '0 8px 8px 0',
        padding: '8px 16px',
        cursor: isDisabled ? 'not-allowed' : 'pointer'
      }}
      disabled={isDisabled}
      onClick={onClick}
    >
      {id.split('-')[1]}
    </button>
  );
}

逻辑解释

  • 父组件的activeButtons状态:用对象来区分不同分组,比如typeA分组的激活按钮ID存在activeButtons.typeA里,这样不同分组之间的状态互不干扰。
  • 点击处理函数handleButtonClick:接收按钮ID和分组类型,判断当前点击的按钮是否已经激活,如果是就取消激活(设为null),否则把该按钮ID设为当前分组的激活状态。
  • 子按钮的isDisabled属性:判断当前分组是否有激活按钮,且当前按钮不是激活的那个,如果满足就禁用。

扩展建议

如果你的项目后续按钮数量很多、层级复杂,也可以考虑用React Context或者Redux来做全局状态管理,但对于当前的需求来说,状态提升的方案已经足够简洁高效,没必要过度复杂化~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:57:13