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

React实现单选按钮组:点击选中一个其余取消选中问题排查

问题根源与修复方案

你的代码里有几个关键问题导致状态滞后:

  • switch语句穿透:handleClick里的每个case都没加break,不管点击哪个按钮,最终都会执行到case 2的逻辑,等于每次点击都会强制选中第三个按钮。
  • 异步状态的错误使用:changeColour中调用setColour后立刻读取colour系列变量,但React的setState是异步的,此时拿到的还是更新前的旧值,导致给DOM添加类名时用了旧状态,显示滞后。
  • 冗余状态+直接操作DOM:同时维护多组状态(colour系列和backgroundColor系列),还手动修改DOM的className,违背了React状态驱动UI的原则,极易出现状态与DOM不一致的情况。

优化后的代码

我们可以简化状态管理,只用一个变量记录选中按钮的索引,完全通过状态驱动UI渲染:

import React from "react";
import '../output.css'
import Images from "./Images";
import { ImageLogo as Img } from "./Images";

export default function Events() {
    const buttonColour = "bg-red-700";
    // 用单个状态记录选中的按钮索引,初始为null表示未选中
    const [selectedIndex, setSelectedIndex] = React.useState<number | null>(null);

    const handleClick = (index: number) => {
        // 点击时直接设置选中索引,自动覆盖之前的选中状态
        setSelectedIndex(index);
    };

    // 根据索引动态生成按钮类名
    const getButtonClass = (index: number) => {
        const baseClass = "w-1.5/12 text-center h-4/6 hover:bg-red-700 rounded-md";
        return selectedIndex === index ? `${baseClass} ${buttonColour}` : baseClass;
    };

    return (
        <div>
            <h1 className="text-white font-bold text-center">EVENT SCHEDULE</h1>
            <div className="Dates flex text-yellow-800 font-bold justify-center h-15-s">
                <p 
                    className={getButtonClass(0)} 
                    onClick={() => handleClick(0)}
                >
                    January 10th
                </p>
                <p 
                    className={getButtonClass(1)} 
                    onClick={() => handleClick(1)}
                >
                    January 11th
                </p>
                <p 
                    className={getButtonClass(2)} 
                    onClick={() => handleClick(2)}
                >
                    January 12th
                </p>
            </div>
            {/* 根据选中索引渲染对应组件 */}
            {selectedIndex === 0 && <Images />}
            {selectedIndex === 1 && <Img />}
            {selectedIndex === 2 && <Img />}
        </div>
    );
}

优化说明

  1. 简化状态管理:只用selectedIndex一个状态变量,统一管理所有按钮的选中状态,避免多状态同步出错。
  2. 状态驱动UI:完全通过状态判断来生成类名,不再手动操作DOM,确保状态与DOM显示始终一致。
  3. 移除冗余代码:删除了无用的ref、多组重复状态和复杂的DOM操作逻辑,代码更简洁易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 20:25:17