Bug: Input of type radio component can't be controlled with an internal state

This issue has been created since 2022-11-22.

I've seen this approach to make a controlled radio input:

function SomeForm() {
  const [gender, setGender] = useState('male');

  const handleChange = (event) => {
    setGender(event.target.value)
  }
  return (
    <form>
        <input type="radio" value="male" checked={gender === 'male'} onChange={handleChange} />
        <input type="radio" value="female" checked={gender === 'female'} onChange={handleChange} />
        <input type="radio" value="transgender" checked={gender === 'transgender'} onChange={handleChange} />
    </form>
  )
}

but I need to create a radio component that manages its state internally and independently:

function Radio({ id, name, value }) {
  const [isChecked, setIsChecked] = useState(false);

  const handleChange = useCallback((event) => {
    setIsChecked(event.target.checked);
  }, []);

  return (
    <input
      type="radio"
      name={name}
      value={value}
      id={id}
      autoComplete="off"
      checked={isChecked}
      onChange={handleChange}
    />
  );
}

but the components get out of sync after a few clicks:

radio-2022-11-22_10.19.39.mp4

I think the onChange event is not firing correctly in this case and a rerender simply doesn't happen since we don't pass the calculated checked value as a prop.

also the checked attribute doesn't update in the DOM and it's problematic since I can't get the checked value and test my component with Testing library. (The main reason is that I can't make a testable radio component without an internal state, it's surely because of my lack of knowledge and any suggestions would be appreciated)

React version: 18.2.0

Steps To Reproduce

  1. click on the first radio input
  2. click on the second radio input
  3. click on the third radio input

Link to code example: https://codesandbox.io/s/nifty-dust-g47gg3?file=/src/App.js

The current behavior

radio states gets out of sync

The expected behavior

radios should remain controlled

mateusmtoledo wrote this answer on 2022-11-25

This is probably expected behavior. When a radio component gets checked, every other with the same name value should be marked as unchecked.

The implementation you have provided, on the other hand, sets the clicked Radio instance's isChecked state to true, but does not update the state on the other instances. This eventually leads to multiple Radio components having a isChecked state of true, which should not happen.

After clicking on each radio, from left to right, the browser correctly keeps track of checked and unchecked radios, leading to something like [false, false, true], but in your React implementation isChecked remains true in every Radio instance (something like [true, true, true]) and, because "change" events are not fired when the user clicks on a checked radio, React won't fire any change events anymore, while native browser events are still fired as expected.

More Details About Repo
Owner Name facebook
Repo Name react
Full Name facebook/react
Language JavaScript
Created Date 2013-05-24
Updated Date 2022-12-10
Star Count 198882
Watcher Count 6638
Fork Count 41302
Issue Count 1120

YOU MAY BE INTERESTED

Issue Title Created Date Comment Count Updated Date
how can i generate apikey 2 2022-01-23 2022-09-15
Response Data of N/A 3 2021-09-07 2022-11-09
How to build with custom network driver 0 2022-08-19 2022-11-11
How can I get the images with the bboxes in the inference? 5 2020-12-09 2022-10-06
question: How does this library compare versus the official `@capacitor/push-notifications` plugin? 1 2022-08-02 2022-09-23
Handling imports from roxygen comment 3 2022-06-23 2022-11-09
Unable to retrieve data into Grafana 4 2020-11-17 2022-12-02
UI: Fix layout overlap issue in XL screens 1 2022-06-22 2022-06-20
Will site be corrected? 2 2022-03-04 2022-12-01
Route calculation in rural, alpine area. 2 2022-10-28 2022-12-06
Show compliance remediation methods in the results 0 2022-07-27 2022-11-12
Unable to read edges from Cosmos DB 0 2021-12-21 2022-12-02
Is the any planning to support JXL? 1 2022-07-20 2022-11-21
Issue processing PDF: "ensureValidFreeList: freelist corrupted" 2 2021-03-20 2022-10-02
本地部署过一段时间之后无法新增编辑文档和登录 1 2022-02-08 2022-11-01
Loading editor saves after update to Godot 3.5 results in some global transform warnings 0 2022-08-10 2022-09-14
Add support for text widgets in 3d 0 2022-08-06 2022-11-02
RFC: flannel with eBPF ? 0 2021-09-15 2022-10-25
Docs are not generated for React.VFC 0 2022-05-16 2022-11-13
Use react-beatiful-dnd with images masonry grid 4 2022-01-20 2022-11-09
I can't close file explorer window when I try to upload a file with sitespeed io docker image 16.8.0 2 2022-04-06 2022-12-03
How to place pathLabel directly on the middle of a line? 9 2022-10-22 2022-11-11
Recent metrics filter change broke metrics collection for non-scientific values 2 2021-12-01 2022-11-08
Error on https://www.coolstreaming.us/forum/arcade/game/6932.html 1 2022-05-29 2022-10-17
Eventing: Expose IMC dispatcher RollingUpdate Strategy controls 6 2021-10-06 2022-09-21
Mass update & Listener 0 2021-02-17 2022-12-02
`-fstack-clash-protection` detection false-positive on ARMv5 with Thumb-1 4 2022-10-27 2022-12-02
Rollbar: "Deadline Exceeded" in EventQueueV2 `dequeue` 1 2022-05-17 2022-11-22
Permission denied on /opt/bitnami/redis-sentinel/etc when sentinel.persistance.enable=false + SecurityContext 2 2022-03-28 2022-12-09
[Not released] [WebAPI] Support the CSS Font Loading API in workers 3 2022-07-25 2022-11-11
Is it possible to access data of drawn data? Like boxes and rules? 4 2021-11-17 2022-09-04
windows11通知栏bug 1 2021-10-06 2022-01-04
amqplib is flooding the queue with messages 2 2021-03-29 2022-11-30
can't run steam on arm64 chroot ubuntu 7 2022-10-16 2022-12-02
Monitoring Tool 6 2021-07-15 2022-01-16
Better shards shuffling in streaming mode 0 2022-02-17 2022-09-26
Cannot use import nor require in demos 0 2022-07-20 2022-11-29
大佬,网络请求中加入显示loading框的功能,状态有点问题 1 2019-11-11 2022-11-16
Aspect ratio is incorrect, particularly with overscan cropped 0 2021-11-05 2022-11-21
affected/package: x.net and x.sys is failing with error "note: module requires Go 1.17" where as go version installed is 1.19 5 2022-11-08 2022-11-15
No info about nodes connected to devices 0 2022-06-15 2022-11-21
textAlign doesn't work 1 2021-10-20 2022-11-02
[Policy Bot] found one or more issues with this repository. 0 2022-11-11 2022-12-09
Redesign idea for Widgets.Toast 2 2020-03-31 2022-12-02
Dropout.tv write-info-json 7 2022-01-16 2022-12-08
docker-desktop trigger msrdc dialog `connection info invalid` (log attached) 13 2022-11-08 2022-11-22
[Bug/Typo] timescaledb-tune not installed by default 3 2020-10-06 2022-11-28
Wireshark protocol plugin support 0 2021-08-08 2022-11-30
嵌套 ConfigProvider 继承失效 3 2022-01-12 2022-08-29
Link for Real-Time Object Detection is leading to wrong repo. 2 2021-10-26 2022-12-01