Preact is checking a radio button without "checked" attribute on DOM
See original GitHub issueReproduction
https://codepen.io/philipmw/pen/abNRQOB
or this standalone HTML file:
<!DOCTYPE html>
<html>
<head>
<script type="module">
import { h, Component, render } from 'https://unpkg.com/preact?module';
const radio1 = h('input', { type: "radio", name: "source", value: "1" });
const radio2 = h('input', { type: "radio", name: "source", value: "2", custom: "custom" });
const radio3 = h('input', { type: "radio", name: "source", value: "3", checked: "checked" });
const app = h('div', null, [radio1, radio2, radio3]);
render(app, document.body);
</script>
</head>
</html>
Steps to reproduce
Open the CodePen, or load the HTML above into your browser.
Expected Behavior
The third radio button is checked, the DOM has the checked
attribute on the third input
element, and my Enzyme/Cheerio unit tests can detect that the third radio button is checked.
Actual Behavior
The third radio button is checked … but the DOM does not reflect this in any way that I can see. There is no checked
attribute on any of the input
elements, and my Enzyme/Cheerio unit tests are unable to detect any of the buttons as checked.
I don’t understand how Preact is even checking the radio button, if not through the checked
attribute.
In contrast, React 16 does apply a checked=""
attribute.
Issue Analytics
- State:
- Created 3 years ago
- Comments:7 (3 by maintainers)
Top Results From Across the Web
Forms | Preact: Fast 3kb React alternative with the same ES6 ...
Checkboxes and radio buttons ( <input type="checkbox|radio"> ) can initially cause confusion when building controlled forms. This is because in an uncontrolled ...
Read more >How can I check whether a radio button is selected with ...
:checked limits it to checkboxes/radio buttons that are selected within the previous group. If you want to avoid this altogether, mark one of...
Read more >HTML DOM Input Radio checked Property - W3Schools
The checked property sets or returns the checked state of a radio button. This property reflects the HTML checked attribute.
Read more >Example - Testing Library
Preact Testing Library works with both Preact Hooks and Classes. Your tests will be the same however you write your components.
Read more >Preact — Checkboxes, Radio Buttons, and Refs - Morioh
Selecting Radio Button by default. If no radio button is selected by the user, no information of the radio buttons is delivered to...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I see. Thank you, @robertknight. I am new to Enzyme and did not realize that I can check props without
.render
beforehand. Indeed that works!I will read your blog post. Thanks for linking me to that.
I move to close this issue. It’s been very educational. I had a number of misconceptions, but now that those are cleared up, I see that everything is working as designed.
That’s definitely not the case as a general statement. At work I have a large number of Preact + Enzyme tests that rely on looking at both properties and attributes.
Typically if you wanted to check the value of a prop passed to an HTML checkbox element created with JSX you would do something like:
Given the above the value of the
checked
prop passed in the<input checked={...}/>
expression will be returned and it doesn’t matter whether Preact sets it as an attribute or a property.What was the reason for using
render()
in the examples above?If for a particular test you really wanted to look at the rendered DOM node then you would use
mount(...)
rather thanshallow(...)
and do something likewrapper.find("input.somecheckbox").getDOMNode().getAttribute("checked")
.In general I recommend always using
mount
rendering. Mocking child components is a good practice if you are writing unit tests rather than integration tests but React/Enzyme’s shallow rendering is not the best way to do this in my view. The problem is that in React shallow rendering works completely differently from normal rendering and this manifests itself in various subtle and not-so-subtle ways. I have a blog post here where I discuss this in more detail and propose alternative ways to achieve this: https://robertknight.me.uk/posts/shallow-rendering-revisited/.