Skip to content

fix(react): clear reflected attributes for nullish props - #31361

Open
ShaneK wants to merge 1 commit into
major-9.0from
fix/31344
Open

fix(react): clear reflected attributes for nullish props#31361
ShaneK wants to merge 1 commit into
major-9.0from
fix/31344

Conversation

@ShaneK

@ShaneK ShaneK commented Aug 15, 2026

Copy link
Copy Markdown
Member

Issue number: resolves #31344


What is the current behavior?

Currently, attachProps assigns every prop onto the element without checking whether it has a value. Assigning a nullish value to a reflected property stringifies it, so an unset optional prop lands as id="undefined" and every element rendered that way shares an id. Setting the prop back to undefined overwrites the attribute rather than removing it. The same goes for title, slot, lang, and dir.

What is the new behavior?

We now remove the attribute after assigning, when the value was nullish and the name is a native property. That is what @lit/react already does in its setProperty, so the hand-rolled wrappers and the generated components behave the same way.

Does this introduce a breaking change?

  • Yes
  • No

In fact, this version of this fix was made explicitly to avoid introducing more breaking changes at this time.

Other information

This replaces #31349, which fixed the same issue by skipping the property assignment for nullish values rather than removing the attribute afterwards. That changes what undefined means for a prop with a declared default. Today <IonModal backdropDismiss={maybeUndefined} /> writes undefined over the @Prop() default of true so the backdrop doesn't dismiss, but with the assignment skipped the default survives and it starts dismissing. Same for animated, showBackdrop, and keyboardClose. It would also leave the package inconsistent, because the generated components go through @lit/react, which does assign, so IonInput and IonButton would disagree about what undefined means. Mirroring @lit/react avoids both, and this PR needs no BREAKING.md entry because of it.

Note that the repro in #31344 uses IonToggle, which is generated on v9 and already passes there. This covers the hand-rolled wrappers @lit/react doesn't touch: the overlays, the routing proxies, and IonApp/IonIcon/IonNav/IonRouterOutlet/the tabs components.

A prop removed from the JSX entirely, rather than set to undefined, still isn't cleared, since attachProps only iterates the new props. That's pre-existing and I left it alone, because three call sites pass a filtered newProps against the full prevProps so the fix isn't as simple as it would appear.

Co-authored-by: Patrick Kenny github@ptmkenny.com

Current dev build:

8.8.19-dev.11786832241.150538c7

@ShaneK
ShaneK requested a review from a team as a code owner August 15, 2026 21:52
@ShaneK
ShaneK requested a review from gnbm August 15, 2026 21:52
@vercel

vercel Bot commented Aug 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ionic-framework Ready Ready Preview Aug 15, 2026 9:52pm

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: react @ionic/react package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant