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

React中实现复选框选中时禁用另一复选框的方法

解决列表项中复选框互斥禁用的问题

我从API获取了列表项数据,每个项设有**Approve(批准)和Decline(拒绝)**两个复选框。需求为选中某一项的Approve复选框时,禁用该项的Decline复选框,反之亦然。以下是我的尝试代码,但未达成预期效果,恳请协助:

function AllReferral() {
    const [buttonStatus1, setButtonStatus1] = useState(false)
    const [buttonStatus2, setButtonStatus2] = useState(false)

    // function
    const deactivateButton2 = () => setButtonStatus1(!buttonStatus1)
    const deactivateButton1 = () => setButtonStatus2(!buttonStatus2)
 
    return (
        <section>
            <div>
                {user?.services?.length > 0 && (
                    <div>
                        <table>
                            <thead>
                                <tr>
                                    <th>Approve</th>
                                    <th>Decline</th>
                                    <th>Service Name</th>
                                </tr>
                            </thead>
                            {user?.services?.map((item, index) => (
                                <tbody key={index}>
                                    <tr>
                                        <td>
                                            <input
                                                name={item?.name}
                                                onClick={deactivateButton2}
                                                type="checkbox"
                                                value={checked}
                                                onChange={(e) => setChecked(e.target.value)}
                                            />
                                        </td>
                                        <td>
                                            <input
                                                name={item?.name}
                                                onClick={deactivateButton1}
                                                type="checkbox"
                                                value={checked2}
                                                onChange={(e) => setChecked2(e.target.value)}
                                            />
                                        </td>
                                        <td>{item?.label}</td>
                                    </tr>
                                </tbody>
                            ))}
                        </table>
                    </div>
                )}
            </div>
        </section>
    );
}

问题分析

  1. 全局状态复用错误:当前使用的buttonStatus1和buttonStatus2是全局状态,所有列表项会共享这两个状态,导致操作任意一个项的复选框都会影响所有项。
  2. 状态绑定缺失:代码中使用的checked和checked2未定义,也未与单个列表项的状态关联,复选框的选中状态无法正确维护。
  3. 事件逻辑混乱:混用onClick和onChange处理状态切换,且未针对单个项做区分,无法实现精准的状态控制。

修正方案

需要为每个列表项单独维护状态,通过对象存储每个服务的审批状态,确保操作单个项时仅影响自身的复选框:

import { useState } from 'react';

function AllReferral() {
    // 用对象存储每个服务的状态,键为服务唯一标识(建议用item.id更稳定)
    const [serviceStatus, setServiceStatus] = useState({});

    // 处理复选框状态变更
    const handleStatusChange = (serviceName, type) => {
        setServiceStatus(prev => ({
            ...prev,
            [serviceName]: {
                // 切换当前类型的选中状态
                [type]: !prev[serviceName]?.[type],
                // 另一个类型设为未选中(如果当前类型被选中)
                [type === 'approved' ? 'declined' : 'approved']: false
            }
        }));
    };
 
    return (
        <section>
            <div>
                {user?.services?.length > 0 && (
                    <div>
                        <table>
                            <thead>
                                <tr>
                                    <th>Approve</th>
                                    <th>Decline</th>
                                    <th>Service Name</th>
                                </tr>
                            </thead>
                            <tbody>
                                {user?.services?.map((item) => (
                                    <tr key={item.name}>
                                        <td>
                                            <input
                                                type="checkbox"
                                                checked={serviceStatus[item.name]?.approved || false}
                                                disabled={serviceStatus[item.name]?.declined || false}
                                                onChange={() => handleStatusChange(item.name, 'approved')}
                                            />
                                        </td>
                                        <td>
                                            <input
                                                type="checkbox"
                                                checked={serviceStatus[item.name]?.declined || false}
                                                disabled={serviceStatus[item.name]?.approved || false}
                                                onChange={() => handleStatusChange(item.name, 'declined')}
                                            />
                                        </td>
                                        <td>{item.label}</td>
                                    </tr>
                                ))}
                            </tbody>
                        </table>
                    </div>
                )}
            </div>
        </section>
    );
}

关键说明

  • 状态存储:使用serviceStatus对象,每个键对应服务的唯一标识,值包含approved和declined两个布尔值,实现单个项的独立状态管理。
  • 复选框属性绑定:
    • checked:绑定对应服务的状态,确保选中状态正确显示。
    • disabled:根据另一个复选框的状态决定是否禁用,实现互斥效果。
  • 事件处理:handleStatusChange函数接收服务标识和状态类型,更新对应服务的状态,同时将另一个状态设为false,确保同一时间只能选中一个复选框。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 04:20:24