Checkbox resets its INTERNAL state in the form and delivers none to FormData after a button with formAction is clicked
Bug report
Suppose we have a form with 1 checkbox and 1 button, and that button has a formAction handler. When clicking the button, the handler is fed with a FormData object. If we select the checkbox, the 1st click to the button delivers its state in that FormData.
But if we click the button the 2nd time, FormData is delivered empty. The same happens in onSubmit handler of the <form> itself. This is all despite the checkbox itself is still visually on.
This happens, because formAction on a button resets the form. So it implicitly resets all of the checkboxes in the form to their default state. But visually, nothing changes, since rendering of the Checkbox state is independent on the actual <input type="checkbox"/> state. There is a huge thread about resetting the form on formData in React repo: https://github.com/facebook/react/issues/29034 - but anyways, since radix-ui hides the actual <input/> element, this all becomes counter-intuitive.
Current Behavior
https://github.com/user-attachments/assets/0b2027e9-d7ad-4906-853e-48c48a93daaf
Expected behavior
After clicking the button the 2nd time, FormData should still contain that checkbox. But for some reason, the checked property of the invisible <input> element gets reset (without re-rendering).
Reproducible example
"use client";
import { Button } from "@/components/ui/button.tsx";
import { Checkbox } from "@/components/ui/checkbox.tsx";
import { useState } from "react";
export default function Page() {
const [checked, setChecked] = useState(false);
console.log("Rendered as:", checked);
return (
<form className="m-10 flex flex-row items-center gap-2">
<Checkbox
name="checkbox"
value="42"
checked={checked}
onClick={() => setChecked(!checked)}
/>
<Button
type="submit"
formAction={(formData) => console.log(formData.getAll("checkbox"))}
>
Submit
</Button>
</form>
);
}
Your environment
| Software | Name(s) | Version |
|---|---|---|
| Radix Package(s) | @radix-ui/react-checkbox | 1.1.4 |
| React | ^19.0.0 | |
| Browser | Chrome | |
| Assistive tech | ||
| Node | n/a | |
| npm/yarn | ||
| Operating System |
I just ran into this, using the checkbox with function actions. The React docs at https://react.dev/reference/react-dom/components/form#handle-form-submission-on-the-client mention:
After the
actionfunction succeeds, all uncontrolled field elements in the form are reset.
It seems the hidden inputs attached to these checkboxes are reset in an unexpected way. This creates some weird bugs, especially with checkbox groups, and I'm not sure the best way to fix this without resorting to hacks.
There must be some workaround? Or do people not really use these components with form actions in React 19?