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

React中如何实现单选按钮:仅保持一个按钮处于激活状态

React实现单选按钮激活状态(同一时间仅一个按钮激活)

你当前的问题在于每个Button组件单独维护自己的isActive状态,兄弟组件之间无法互相影响,所以没法实现单选效果。在React里,这种需要跨组件同步的状态,应该把状态提升到共同的父组件来管理,而不是直接操作DOM或者用useRef(除非特殊场景)。

解决方案步骤:

  1. 将激活状态移到父组件:父组件维护当前激活的按钮标识(比如按钮的data属性值),所有按钮的激活状态由父组件统一控制。
  2. 修改Button组件:去掉自身的useState,改为从props接收isActive状态和点击回调函数。
  3. 父组件控制状态更新:点击按钮时,父组件更新激活标识,所有按钮根据这个标识判断自己是否激活。

修改后的Button组件代码:

import React from 'react';

const Button = ({ text, data, isActive, onClick }) => {
  const activeLink = 'bg-light-one text-main-color text-light-one rounded-[2rem] border-none outline-none my-[0.45rem] mx-[0.4rem] py-[0.85rem] px-[1.8rem] uppercase font-medium leading-none cursor-pointer transition duration-300';
  const normalLink = 'text-lg bg-transparent text-light-one rounded-[2rem] border-none outline-none my-[0.45rem] mx-[0.4rem] py-[0.85rem] px-[1.8rem] uppercase font-medium leading-none cursor-pointer transition duration-300';
  
  return (
    <button 
      onClick={() => onClick(data)} 
      type='button' 
      data-filter={data} 
      className={isActive ? activeLink : normalLink}
    >
      {text}
    </button>
  );
};

export default Button;

父组件示例代码:

import React, { useState } from 'react';
import Button from './Button';

const ButtonGroup = () => {
  // 存储当前激活按钮的data值,初始为null表示无激活状态
  const [activeFilter, setActiveFilter] = useState(null);

  const handleButtonClick = (filterData) => {
    // 点击时更新激活状态为当前按钮的data值
    setActiveFilter(filterData);
  };

  return (
    <div>
      <Button 
        text="全部" 
        data="all" 
        isActive={activeFilter === "all"} 
        onClick={handleButtonClick} 
      />
      <Button 
        text="分类1" 
        data="category1" 
        isActive={activeFilter === "category1"} 
        onClick={handleButtonClick} 
      />
      <Button 
        text="分类2" 
        data="category2" 
        isActive={activeFilter === "category2"} 
        onClick={handleButtonClick} 
      />
    </div>
  );
};

export default ButtonGroup;

为什么不用useRef或直接操作DOM?

React的核心是状态驱动视图,直接操作DOM会导致视图和状态不一致,增加维护难度。状态提升的方式完全遵循React的单向数据流,逻辑清晰且易于维护。如果非要用DOM操作的方式(不推荐),你可以在父组件用useRef存储所有按钮的DOM节点,点击时遍历移除所有按钮的activeLink类,再给当前按钮添加,但这种方式违背了React的设计理念,不建议使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 06:47:24