skip to Main Content

I have a function for a keyDown event:

<Table.Row
    key={item.id + "-" + index}
    className="align-top"
    onKeyDown={actionOnEnter(() => {
        saveRow(index);
    })}
>

I can see in console that event.target property has a nodeName property.
I would like to check in the event function the value of the nodeName property.

export const actionOnEnter = (fn: () => void) => (e: React.KeyboardEvent) => {
    console.log(e.target.nodeName);
    if (e.key === "Enter") {
        e.preventDefault();
        fn();
    }
};

But, I get typescript error if I try to get a value of nodeName property:

TS2339: Property  nodeName  does not exist on type  EventTarget

Which property and type should I use to get a node element which triggered the event?

2

Answers


  1.   const actionOnEnter = (fn: () => void) => (e: React.KeyboardEvent) => {
        if (e.target instanceof HTMLElement) {
          console.log(e.target.nodeName); // Safely access nodeName
        }
    
        if (e.key === "Enter") {
          e.preventDefault();
          fn();
        }
      };
    Login or Signup to reply.
  2. In the context of a React.KeyboardEvent<Element>, the target property is typed as an EventTarget. However, EventTarget does not have a nodeName property; this property is specific to Node.

    The EventTarget interface in React only includes methods for adding, removing, or dispatching events.

    If we know that the event is attached to an element, we can cast the target property to a Node. Alternatively, we can cast it as an Element or HTMLElement, depending on the desired specificity.

    export const actionOnEnter = (fn: () => void) => (e: React.KeyboardEvent) => {
      const el = e.target as Node;
    
      console.log(el.nodeName); // Property is now available
      
      if (e.key === "Enter") {
          e.preventDefault();
          fn();
      }
    };
    

    For safer type checking, we can use a guard clause to ensure the target is an instance of Node before accessing nodeName:

    export const actionOnEnter = (fn: () => void) => (e: React.KeyboardEvent) => {
      if (e.target instanceof Node) {
        console.log(e.target.nodeName); // The `target` is inferred as a `Node`
      }
    
      if (e.key === "Enter") {
          e.preventDefault();
          fn();
      }
    };
    

    The guard clause narrows the type of target within the if block, allowing it to be treated as a Node. This ensures type safety and eliminates the need for temporary variables or unsafe casting in that scope.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search