Reputation: 3
This is somewhat of weird question. I'm working with event types in React, and we want to use onClick in some instances, and onPointerDownCapture in others (for reasons). But to make this more general, it could be any two different click-like events. The issue is that while we can assign whatever function handler on the right side of the expression, the left side has to be static, essentially. So,
<button
onClick={handler}
vs onPointerDownCapture={handler}
vs onMouseDown={handler}
/>
I think just using onPointerDownCapture will be fine for most usecases, but in a perfect world, I'd be able to flip between these at runtime based on other variables. Is it possible to override the onClick on the button/div/whatever prototype or something to be whatever event type I want it to be?
Much googling. No success.
Upvotes: 0
Views: 1668
Reputation: 960
I think best is @vera solution in comment. Pass extra prop to component (for example isOnClick), and based on it pass either callback or undefined to event handler prop:
function Component(props: { isOnClick: boolean; callback: () => void }) {
return (
<div
onClick={props.isOnClick ? props.callback : undefined}
onMouseDown={props.isOnClick ? undefined : props.callback}
/>
);
}
Note that passing undefined to prop is same as not setting that prop.
Alternatively conditionaly return component:
function Component(props: { isOnClick: boolean; callback: () => void }) {
if (props.isOnClick) {
return <div onClick={props.callback}/>
} else {
return <div onMouseDown={props.callback}/>
};
}
Upvotes: 0
Reputation: 19987
I didn’t fully understand what you mean by “overriding onClick”, but
The issue is that while we can assign whatever function handler on the right side of the expression, the left side has to be static, essentially.
This is not true, left hand side could be dynamic, here’s how:
<button {...({ [eventName]: handler })} />
I guess this solves your problem.
Ok above syntax is a bit terse and admittedly confusing. It’s the good old JSX spread props syntax, just over an inline object literal.
I’ll give you another equivalent form, hopefully it should be more readable.
const eventName = someCondition ? "onPointerDownCapture" : "onClick"
const props = {
[eventName]: handler
}
<button {...props} />
Upvotes: 2
Reputation: 324
You have to use those attribute names and you use the same function name for all 3 of them.
What these 3 attributes do is they register the associated event.
Maybe you could use a useEffect
and add there conditionally an event listener instead of the proposed React attributes.
Upvotes: 0