React TypeScript get Data Attribute From Click Event
Use e.currentTarget and then use HTML standard method getAttribute
. No coercion necessary.
const appMode = e.currentTarget.getAttribute('data-appmode');
(note lowercase in the attribute name to avoid warnings from react)
currentTarget
is already correctly typed.
If you read the definitions of React's event types you can see that MouseEvent
extends SyntheticEvent
, which extends BaseSyntheticEvent
, which includes the property target
and currentTarget
, among others. The HTMLElement
type you provide gets applied to currentTarget
, so you have access to all the right stuff. If you use target
you'll get a compile error about getAttribute
not being valid for type EventTarget
.
What's the difference?
The currentTarget
is the element where you're putting your handler, onClick
. The target
is where the event originally came from (more here). This is not necessarily the same because events bubble up. See the PR referenced in the type definitions file for a complete discussion on why they're typed differently.
Using typescript I've recently learnt of the following approach:
type TabsProps = {
activeTab: string,
items: string[],
setActiveTab: (i: string) => void,
}
const Tabs = ({ items, activeTab, setActiveTab }: TabsProps) => {
const onClick: React.MouseEventHandler<HTMLElement> = (e) => {
setActiveTab(e.currentTarget.dataset.id)
//console.log(e) // <a data-id="0" class="active nav-link">Info</a>
}
return (
<Nav tabs >
{
items.map((x, i) => (
<NavItem key={i}>
<NavLink className={activeTab === i.toString() ? 'active' : ''} onClick={onClick} data-id={i}>{x}</NavLink>
</NavItem>
))
}
</Nav >
);
}
You most likely will have to use as
syntax , depending which property you want to access on e.target.
handleAppModeClick(e: React.MouseEvent) {
const appMode = (e.target as HTMLButtonElement).getAttribute('data-appMode');
}