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

React可复用单选框组件:点击已选单选框取消选中功能求助

问题描述

我正在为React可复用单选框组件添加功能——点击已选中的单选框时取消其选中状态,但handleRadioChange函数中的逻辑无法生效,预期行为是再次点击已选中单选框时取消选中,求实现建议。

现有代码
import {
  FormControl,
  FormControlLabel,
  Radio,
  RadioGroup,
} from '@material-ui/core'
import clsx from 'clsx'
import React from 'react'
import { useStyles } from './index.styles'
import OpenInNewIcon from '@mui/icons-material/OpenInNew'
import { isEmpty } from 'lodash'
import { RadioButtonType } from 'labrav-react-components'
import { RadioButtonGroupMapping } from 'labrav-react-components'

export type RadioButtonsProps = {
  checkedValue?: { key: string; value: string }
  handleChange: (event: React.ChangeEvent<HTMLInputElement>) => void
  radioButtonMappings: RadioButtonGroupMapping[]
  customChild?: JSX.Element
}
export const NewRadioButtons: React.FC<RadioButtonsProps> = ({
  checkedValue,
  handleChange,
  radioButtonMappings,
  customChild,
}) => {
  const classes = useStyles()
  
   const handleRadioChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const selectedValue = event.target.value
    const isSameValue = selectedValue === checkedValue?.value
    if (isSameValue) {
     handleChange({
      target: { value: ''},
    } as React.ChangeEvent<HTMLInputElement>)
    } else {
      handleChange(event)
    }
  }


  return (
    <FormControl>
      <RadioGroup
        aria-labelledby="radio-buttons-group"
        name="radio-buttons-group"
        value={checkedValue ? checkedValue?.value :''}
        onChange={handleRadioChange}
        data-testid="radio-group"
        row
        className={classes.root}
      >
        {radioButtonMappings.map(radioButtonMapping => {
          return (
            <div
              key={radioButtonMapping.key}
            >
              <FormControlLabel
                value={radioButtonMapping.key}
                control={<Radio className={classes.radio}  />}
                label={radioButtonMapping.label}
                className={classes.radioLabel}
                data-testid="radio-label"
                disabled={radioButtonMapping?.disabled || false}
              />
              {radioButtonMapping.key !== RadioButtonType.CUSTOM &&
                !isEmpty(radioButtonMapping.url) && (
                  <a
                    style={{ height: '18px' }}
                    href={radioButtonMapping.url}
                    target="_blank"
                  >
                    <OpenInNewIcon className={classes.openNewIcon} />
                  </a>
                )}
              {checkedValue &&(checkedValue.key === radioButtonMapping.key &&
              radioButtonMapping.type === RadioButtonType.CUSTOM) ? (
                <> {customChild} </>
              ) : null}
            </div>
          )
        })}
      </RadioGroup>
    </FormControl>
  )
}
实现建议
  • 核心问题:值匹配逻辑错误
    当前代码中,FormControlLabel的value绑定的是radioButtonMapping.key,但判断是否重复选中时用的是selectedValue === checkedValue?.value,同时RadioGroup的value绑定的是checkedValue?.value——把key和value两个不同字段混在一起比较,直接导致判断逻辑失效。

  • 具体修改步骤

    1. 统一RadioGroup的value绑定维度,和FormControlLabel保持一致:
      <RadioGroup
        // 其他属性不变
        value={checkedValue ? checkedValue.key : ''}
      />
      
    2. 修正handleRadioChange中的判断逻辑,用key来识别已选中项:
      const handleRadioChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        const selectedKey = event.target.value
        const isSameKey = selectedKey === checkedValue?.key
        if (isSameKey) {
          // 取消选中,通知父组件清空选中值
          handleChange({
            target: { value: '' },
          } as React.ChangeEvent<HTMLInputElement>)
        } else {
          handleChange(event)
        }
      }
      
    3. 同步父组件逻辑:当收到value为空的事件时,将checkedValue更新为undefined或{ key: '', value: '' },确保RadioGroup能正确呈现未选中状态。
  • 补充说明
    Material-UI的RadioGroup是通过value属性匹配选中项的,只有当RadioGroup的value与某个FormControlLabel的value完全一致时,对应的单选框才会被选中。所以必须保证两者使用同一维度的标识(这里统一用key),逻辑才能正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 01:28:33