Home > Net >  Property 'dataset' does not exist on type 'EventTarget' for list element
Property 'dataset' does not exist on type 'EventTarget' for list element

Time:11-06

I have an autocomplete component that has a list full of the autcomplete options. These options are all in li tags. When I setInputs in the onClick event I am seeing that the e.target.dataset.id has a typescript error that says "Property 'dataset' does not exist on type 'EventTarget' for list element". I cant quite figure out what the onClick event type so be then.

  const handleAutoCompleteClick = (e: React.MouseEvent) => {
       setInputs((inputs) => ({ ...inputs, food: e.target.dataset.id }));
  };

   <li
     key={i}
     className={i === active ? "active" : ""}
     onClick={handleAutoCompleteClick}
     data-id={option.id}
    >
     {option.text}
    </li>

CodePudding user response:

  • You need to specify that the event is for an HTMLElement (because those elements have datasets) - otherwise TypeScript will only see it as an Element, which may not
  • You should reference e.currentTarget instead of e.target - e.currentTarget will refer to the element the listener is attached to, rather than a possible descendant that the event was dispatched to
  • The dataset value may still be undefined, so you'll need a non-null assertion
const handleAutoCompleteClick = (e: React.MouseEvent<HTMLElement>) => {
    setInputs((inputs) => ({ ...inputs, food: e.currentTarget.dataset.id! }));
};

But a better way to do this in React would be not to pass the data from React into the DOM and then back into React, but to do so through React's JavaScript alone, with a closure.

<li
  key={i}
  className={i === active ? "active" : ""}
  onClick={() => {
    setInputs((inputs) => ({ ...inputs, food: option.id }));
  }}
 >
  {option.text}
 </li>

It's also sometimes a bad idea to use the array index as the key for an element, especially if items might be added or removed from the array. Because the option being iterated over has an id property, consider using that instead, if it's unique.

<li
  key={option.id}
  • Related