最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do you toggle the checked value of a radio button in react using hooks? - Stack Overflow

programmeradmin1浏览0评论

I have a group of radio buttons being built up from some external data, as per the examples below. They render and work as I'd expect with the exception of the aria-checked attribute. Clicking a radio button toggles the checked value, but it remains true when another has been selected.

If I click each radio button in sequence, I end up with a list of radio buttons that display aria-checked="true" which obviously isn't the best experience.

I'm not sure how to go about toggling the radio buttons checked value back to false when another has been checked.

Any help would be great!

Input:

    const [isChecked, setIsChecked] = useState(false);

    <Input
        type={type}
        id={id}
        value={id}
        name={name}
        aria-label={label}
        aria-checked={isChecked}
        onChange={() => setIsChecked(!isChecked)}
    />
    <Label htmlFor={id}>{label}</Label>

Usage:

    <fieldset>
        {someData.map(item => {
            return (
                <RadioButton
                    type="radio"
                    key={item.id}
                    id={item.id}
                    name={item.name}
                    label={item.label}
                />
            );
        })}
    </fieldset>

I have a group of radio buttons being built up from some external data, as per the examples below. They render and work as I'd expect with the exception of the aria-checked attribute. Clicking a radio button toggles the checked value, but it remains true when another has been selected.

If I click each radio button in sequence, I end up with a list of radio buttons that display aria-checked="true" which obviously isn't the best experience.

I'm not sure how to go about toggling the radio buttons checked value back to false when another has been checked.

Any help would be great!

Input:

    const [isChecked, setIsChecked] = useState(false);

    <Input
        type={type}
        id={id}
        value={id}
        name={name}
        aria-label={label}
        aria-checked={isChecked}
        onChange={() => setIsChecked(!isChecked)}
    />
    <Label htmlFor={id}>{label}</Label>

Usage:

    <fieldset>
        {someData.map(item => {
            return (
                <RadioButton
                    type="radio"
                    key={item.id}
                    id={item.id}
                    name={item.name}
                    label={item.label}
                />
            );
        })}
    </fieldset>
Share Improve this question asked Mar 10, 2020 at 17:48 NickNick 2,5595 gold badges39 silver badges72 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 4

You could try something like this.

const Radio = React.memo(function Radio({
  item,
  checked,
  onChange
}) {
  console.log("rendering", item.label);
  return (
    <label>
      {item.label}
      <input
        type="radio"
        value={item.id}
        checked={checked}
        onChange={onChange}
      />
    </label>
  );
});
const RadioList = ({ items, value, onChange }) => (
  <div>
    {items.map(item => (
      <Radio
        item={item}
        key={item.id}
        checked={item.id === value}
        onChange={onChange}
      />
    ))}
  </div>
);

const App = ({ items }) => {
  const [value, setValue] = React.useState(items[0].id);
  const [v, setV] = React.useState(items[1].id);
  const onChange = React.useCallback(
    e => setValue(e.target.value),
    []
  );
  const onOther = React.useCallback(
    e => setV(e.target.value),
    []
  );
  return (
    <div>
      <RadioList
        items={items}
        value={value}
        onChange={onChange}
      />
      <RadioList
        items={items}
        value={v}
        onChange={onOther}
      />
    </div>
  );
};
//render app
ReactDOM.render(
  <App
    items={[
      { id: "1", label: "one" },
      { id: "2", label: "two" },
      { id: "3", label: "three" },
      { id: "4", label: "four" }
    ]}
  />,
  document.getElementById("root")
);
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

There are two things you should change here.

  1. When you are rendering a list of radio buttons under the same group, then the name attribute should be same for all the radio buttons. So instead of reading the name attribute from the someData, pass the same name attribute to each button. Or keep the same name in someData for each object.

  2. After that, I don't think the state should be on input ponent because once you checked the radio, you are never changing its value even after clicking on some radio button. You can try it keeping the same name attribute on each Radio button.

So the solution can be to actually pass the checked attribute to the Input ponent depending upon which radio is actually selected. Please check the following code:

const RadioButton = ({ type, id, name, label, checked, onChange }) => {
return (
    <>
        <input
            type={type}
            id={id}
            value={id}
            name={name}
            aria-label={label}
            aria-checked={checked}
            checked={checked}
            onChange={onChange}
        />
        <label htmlFor={id}>{label}</label>
    </>
)

}

const RadioGroup = () => {
const someData = [{
    id: 1,
    name: 'name',
    label: 'name 1'
}, {
    id: 2,
    name: 'name',
    label: 'name 2'
}, {
    id: 3,
    name: 'name',
    label: 'name 3'
}];

const [checkedValue, setIsChecked] = useState(1);

return (
    <fieldset>
        {someData.map(item => {
            return (
                <RadioButton
                    type="radio"
                    key={item.id}
                    id={item.id}
                    name="radioGroup"
                    label={item.label}
                    checked={checkedValue === item.id}
                    onChange={() => setIsChecked(item.id)}
                />
            );
        })}
    </fieldset>
)

}

发布评论

评论列表(0)

  1. 暂无评论