[Slot] Slot passes functions to it's children for onX handler properties, even when the onX handler is falsey
See original GitHub issueBug 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:
- Created a year ago
- Reactions:2
- Comments:5

Top Related StackOverflow Question
Great, I’ll prepare a PR then.
And thanks so much for the kinds words! ♥️
Hey @benoitgrelard thanks for the thorough replies!
You are right on
onClickand 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 useonDeleteto 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) 💯