带有 React 的单选按钮

Radio Button with React

我的单选按钮不能正常工作,最大的问题是当我点击单选项目时没有设置选中的属性。

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

请查看下面的代码段,它在这里不起作用,不知道为什么。

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>

如有任何帮助,我们将不胜感激。

我认为您的问题出在输入的 name 属性上。您为每个输入赋予不同的名称,以便使每个输入属于不同的组。所有无线电输入必须具有相同的名称(参见 here)或根本没有 name 属性。

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

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

查看这个简单的代码片段:

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>

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