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.

[Slot] Slot passes functions to it's children for onX handler properties, even when the onX handler is falsey

See original GitHub issue

Bug report

I consider this a bug given my use case, but it may be considered expected behaviour.

Current Behaviour

The Slot component has code that wraps onX handlers so that handlers from the Slot parent (such as Tooltip) are called. However, it doesn’t check whether the handler on the child is actually truthy before wrapping it, which causes it to suddenly be defined on the child component - even if it’s value has explicitly been set to undefined.

In cases where child components render (or do something else) based on whether a handler is defined, this causes any properties starting with onX to always be defined - even in those cases where it may intentionally (such as a conditional) be undefined in the component.

The codesandbox has an example, but some code (where Tooltip is a wrapper around the radix Tooltip primitive):

<Tooltip title="Example tooltip">
    <Tag onDelete={somethingIsTrue ? () => alert('delete') : undefined}>Example</Tag>
</Tooltip>

If Tag has code that does/renders something depending on onDelete being defined, it is always defined when wrapped in a Tooltip - because Slot does that wrapping in the code linked above. This is the case for any onX handler, even if it is an entirely custom, non native dom event handler such as onSomethingCompletelyRandom.

It is also always defined for onClick, presumably due to this code in Tooltip itself. I expect resolving that is slightly more challenging than resolving it for other handlers.

Expected behaviour

Passing undefined (or another falsey value) to any property named onX should follow through to the child component.

Reproducible example

https://codesandbox.io/s/keen-dan-c6u5yv?file=/App.js

Suggested solution

Check whether onX handlers are truthy inside Slot before wrapping them - by changing isHandler to isHandler && childProps[propName].

For those (such as onClick) that are defined explicitly inside the Slot parents, like those defined in Tooltip, this solution wouldn’t really work, you’d have to exclude them explicitly from the check (or change the clause to isHandler && (slotProps[propName] || childProps[propName])

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:2
  • Comments:5

github_iconTop GitHub Comments

1reaction
benoitgrelardcommented, Oct 11, 2022

Great, I’ll prepare a PR then.

And thanks so much for the kinds words! ♥️

1reaction
mattdalycommented, Oct 11, 2022

Hey @benoitgrelard thanks for the thorough replies!

You are right on onClick and handlers coming from the slot being a bad idea, that one was just an example and not one we actively intend to use - I just wanted to highlight the different behaviours there. We do use onDelete to display a delete/remove button but that api may change, composition would be probably be preferred as you mention (that’s also my most liked api decision in Radix).

The proposed solution looks like it solves the issue and is also close to what we have patch-package’d in our WIP drafts.

Thanks for the response (and the great library) 💯

Read more comments on GitHub >

github_iconTop Results From Across the Web

How do I pass data into a slotted element in Lit - Stack Overflow
One way to set the mydata property on all slotted children is to listen to the slotchange event and then update the property...
Read more >
Untitled
Under the skin rash all over body, Glass wool insulation r value, Onyx all we got ... Modutih 2015, Magasin c10count, Sharepoint event...
Read more >
User Guide - The Onyx Platform
The information model for an Onyx workflow has the distinct advantage that it's possible to compile other workflow representations (perhaps a ...
Read more >
Public Law 110-161 - GovInfo
1844]] Public Law 110-161 110th Congress An Act Making appropriations for the Department of State, foreign operations, and related programs for the fiscal ......
Read more >
axe-core/axe.js - chromium/src/third_party - Git at Google
forEach(this.handlers, function forEachHandler(h) { ... var result = false; ... throw new TypeError('You must pass a resolver function as the first argument ...
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