React中如何实现单选按钮:仅保持一个按钮处于激活状态
React实现单选按钮激活状态(同一时间仅一个按钮激活)
你当前的问题在于每个Button组件单独维护自己的isActive状态,兄弟组件之间无法互相影响,所以没法实现单选效果。在React里,这种需要跨组件同步的状态,应该把状态提升到共同的父组件来管理,而不是直接操作DOM或者用useRef(除非特殊场景)。
解决方案步骤:
- 将激活状态移到父组件:父组件维护当前激活的按钮标识(比如按钮的
data属性值),所有按钮的激活状态由父组件统一控制。 - 修改Button组件:去掉自身的
useState,改为从props接收isActive状态和点击回调函数。 - 父组件控制状态更新:点击按钮时,父组件更新激活标识,所有按钮根据这个标识判断自己是否激活。
修改后的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
相关产品推荐
相关产品推荐

