带有 React 的单选按钮

Posted

技术标签:

【中文标题】带有 React 的单选按钮【英文标题】:Radio Button with React 【发布时间】:2021-06-19 06:12:30 【问题描述】:

我的单选按钮无法正常工作,最大的问题是当我单击单选项目时,未设置选中的属性。

知道为什么它不能正常工作以及如何实现上述几点吗?

请看下面的片段,这里不工作不知道为什么。

class Root extends React.Component 
  render() 
    return (
        <div>
        Group 1: <RadioButton />
        Group 2: <RadioButtonGroup />
      </div>
    );
  


import React,  useState  from "react"

interface SharedProps 
  /**
   * Specify whether the control is disabled
   */
  disabled?: boolean

  /**
   * Specify whether the <RadioButton> is currently checked
   */
  defaultChecked?: boolean

  /**
   * Provide where label text should be placed
   */
  labelPosition: "right" | "left"

  /**
   * Provide a name for the underlying `<input>` node
   */
  name: string

  /**
   * Provide an optional `onChange` hook that is called each time the value of
   * the underlying `input` changes
   */
  onChange?: (event: React.ChangeEvent<htmlInputElement>) => void


export interface RadioButtonProps extends SharedProps 
  /**
   * Provide label text to be read by screen readers when interacting with the
   * control
   */
  labelText: string

  /**
   * Specify the value of the <RadioButton>
   */
  value: string | number

  /**
   * Specify whether the <RadioButton> is currently checked
   */
  checked: boolean

  /**
   * Specify whether the label should be hidden, or not
   */
  hideLabel: boolean

  /**
   * Event – on click
   */
  onClick?: (event: React.MouseEvent<HTMLInputElement>) => void

  // Radio Btn Label next to Radio input.
  inputLabel?: string

  // Field required
  required?: boolean


export interface RadioButtonGroupProps extends SharedProps 
  // Radio Btn Label next to Radio input.
  inputLabelGroup?: string

  /**
   * Provide a collection of components to render in the group
   */
  items: Array<RadioButtonProps>
  /**
   * Provide where radio buttons should be placed
   */
  orientation: "horizontal" | "vertical"

  /**
   * Specify the value of the <RadioButton>
   */
  valueSelected: string | number


export const RadioButton = (
  labelText,
  value,
  checked,
  hideLabel,
  onClick,
  inputLabel,
  required,
  disabled,
  defaultChecked,
  labelPosition,
  name,
  onChange,
: RadioButtonProps) => 
  const [isChecked, setIsChecked] = useState(checked)
  return (
    <div>
      <input
        id="radiobutton-1"
        type="radio"
        name=name
        required=required
        disabled=disabled
        aria-label="example"
        value=value
        checked=isChecked
        onChange=onChange
        onClick=() => setIsChecked(!isChecked)
        defaultChecked=defaultChecked
      />

      <label htmlFor="radiobutton-1">
        !hideLabel && <span aria-label=labelText>inputLabel</span>
      </label>
    </div>
  )


// Default Value of hideLabel
RadioButton.defaultProps = 
  hideLabel: false,
  checked: false,


export const RadioButtonGroup = (
  orientation,
  valueSelected,
  disabled,
  // defaultChecked,
  labelPosition,
  inputLabelGroup,
  name,
  items,
  onChange,
: RadioButtonGroupProps) => 
  const [active, setActive] = useState(Number)
  const mappedItems = items.map(
    ( inputLabel, labelText, value, hideLabel, required , index) => (
      <RadioButton
        name=name
        key=index
        inputLabel=inputLabel
        required=required
        
        checked=active === index
        
        onClick=() => setActive(index)
        onChange=onChange
        labelText=labelText
        value=value
        disabled=disabled
        hideLabel=hideLabel
        
        labelPosition=labelPosition
      />
    )
  )
  return (
    <div>
      <label>inputLabelGroup</label>
      mappedItems
    </div>
  )


ReactDOM.render(
  <Root />,
  document.getElementById('container')
);
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="container"></div>

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

我认为您的问题在于您输入的 name 属性。你给每个输入一个不同的名字,这样你就可以让每个输入属于不同的组。所有无线电输入必须具有相同的名称(请参阅here)或根本没有name 属性。

顺便说一句,在大多数情况下,您在编写 React 代码时不需要添加 id 属性。

useState 函数也接受默认状态作为参数,而不是类型。

看这个简单的代码sn-p:

class Root extends React.Component 
  render() 
    return (
        <div>
        Group 1: <RadioGroup />
        Group 2: <RadioGroup />
      </div>
    );
  


const RadioGroup = () =>
   const [active, setActive] = React.useState(0);
   return (
    <div>
      <input type="radio" checked=active==0 onClick=() => setActive(0) />
      <input type="radio" checked=active==1 onClick=() => setActive(1) />
    </div>
   );


ReactDOM.render(
  <Root />,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>

<div id="container"></div>

如果我能给你一个小提示:当试图找出代码中的问题时,尽量简化代码并删除不必要的元素,如样式元素等。如果您将此代码发布到 SO,审核您的代码会更容易。

【讨论】:

谢谢,但请您再次检查我输入的 sn-p.. 我做了一些更改。为了更容易理解。#

以上是关于带有 React 的单选按钮的主要内容,如果未能解决你的问题,请参考以下文章

React 中的单选按钮选择

如何检测 React App 中更改的单选按钮

取消选中带有 Material UI 的单选按钮

React.js - 如何设置选中/选中的单选按钮并跟踪 onChange?

带有多个单选按钮的多个问题c#

带有工具栏的菜单中的单选按钮样式不起作用