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');
}