question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Preact is checking a radio button without "checked" attribute on DOM

See original GitHub issue

Reproduction

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:closed
  • Created 3 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
philipmwcommented, Sep 23, 2020

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.

1reaction
robertknightcommented, Sep 23, 2020

However, the way Enzyme hands the element to Cheerio is through the rendered HTML. If my assessment is right, this means that there is no way to read any property in Enzyme tests—only attributes.

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:

wrapper.find("input.somecheckbox").prop("checked")

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 than shallow(...) and do something like wrapper.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/.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found