-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Trouble controlling checkbox #3486
Comments
As @JoviDeCroock's tag implies, this is fixed in the next major release of Preact. In the meantime, there are actually two separate things happening here: one is that Preact 10 doesn't quite cover all controlled components cases, and the other is an oddity in the way checkboxes work in the DOM. The latter DOM issue is an interesting one. The behavior here can be recreated identically with or without Preact: let checkbox = document.createElement('input');
checkbox.type = 'checkbox';
document.body.appendChild(checkbox);
checkbox.onclick = e => {
checkbox.checked = true;
e.preventDefault();
}; (here's that code running on JSFiddle: https://jsfiddle.net/developit/bdx8kmwu/) There are two workarounds for this: one is to avoid calling preventDefault on click events generated by a checkbox. In Preact 10, that will cause the component to become uncontrolled, so it's not useful until that fix rolls out. The other solution is to defer the assignment of checkbox.onclick = e => {
+ setTimeout(() => {
checkbox.checked = true;
+ });
e.preventDefault();
}; (notice how this fixes the issue when working directly with the DOM: https://jsfiddle.net/developit/3a9eysxh/) It's not an ideal solution, for sure, but it does work. In Preact, you can simply wrap the state setter in a setTimeout: function click(ev) {
- setState(true);
+ setTimeout(() => setState(true));
ev.preventDefault()
} |
Thank you for the response. I forgot to mention that I worked around the issue with set timeout in my ticket. Appreciate all the work being done |
I will close this ticket as it's present in v11 and we have a workaround provided, thank you so much for taking the time to reproduce and everything! |
Sorry to resurrect this, but since this is fixed in 11, and still present in the latest release of 10, and 11 doesn't have a firm release (as per #2621), I'm wondering if the fix could be backported? I see https://preactjs.com/guide/v10/forms#checkboxes--radio-buttons too, which maybe means this is no longer considered a 'fix', and we should use controlled inputs only? But it was very confusing that this code resulted in an uncontrolled input in Preact, whether or not controlled inputs are suggested as a way forward (which will personally take me a long time to wrap my head, and our codebase, around, coming from React). <div>
<input type="checkbox" id={"my special id"} name={"some name"} checked={true} />
<label htmlFor={"my special id"}>
hi
</label>
</div> |
Unlikely; there's been a few attempts but none have worked out.
Controlled inputs aren't really a thing in Preact, so you can't only use them. Refs, as we mention at the top of the forms doc, is the way to go about controlling inputs if you need to. |
Sorry, I meant uncontrolled as per that docs page and PR discussion. I was surprised this was the recommendation because so far Preact is working fine with all our controlled inputs with react-bootstrap 😅 Thanks for the update! |
More likely they don't really make use of being controlled, which is actually pretty common. But yeah, generally better to use uncontrolled when possible, the DOM is perfectly capable of handling state in most cases. When you need tighter control, refs are there, but no need to jump to using them until needed. |
Describe the bug
I cannot get a controlled checkbox to work in preact
To Reproduce
See simple example
https://codesandbox.io/s/preact-controlled-checkbox-w1fn9g
Steps to reproduce the behavior:
Expected behavior
the checkbox should be controlled by state
React example of the same controlled checkbox
https://codesandbox.io/s/react-controlled-checkbox-lebx4j
The text was updated successfully, but these errors were encountered: