Donʼt entirely trust Reactʼs events

In React, browser events differ slightly from Vanilla JavaScript, as a wrapper has been built on the existing browser events interface to ensure consistent behaviour across browsers (RIP, IE) - Synthetic events

Reminder

  • Events bubble in React by default.

  • React’s onchange event is actually JavaScript’s input event.

      // React's onChange is JavaScript's onInput, so InputEvent
      (nativeEvent as InputEvent).inputType !== `deleteContentBackward`
    

    For whatever reason they modified the change event, the existing input event could have just been used - https://github.com/facebook/react/issues/9567

Scenario

A one-time-password component

Instead of adding eventsʼ listeners to each input element, add it to the parent element (it should make a difference in performance, depending on the use-case) - it's a technique called event delegation; conversely, early optimization should be avoided.

return (
    <form
      className='form-otp'
      onSubmit={handleSubmit}
      onChange={handleChange}
      onKeyDown={handleKeyDown}
      onKeyUp={handleKeyUp}
      onPaste={handlePaste}
    >

The eventʼs target, the element that actually caused the event, is accessed like so:

function handleKeyUp({ key, target }: KeyboardEvent) {
    const $input = target as HTMLInputElement
}

During development, we all do console.logs to check for a variable’s value; a rather surprising thing is when you console.log the target & the currentTarget, you get the element that actually triggered the event as the target & null for the currentTarget, which is supposed to be the parent (form) element. Use event.currentTarget in code and you realise itʼs not null.

Apparently, before React 17, it had to do with something called event pooling; Reactʼs Synthetic events are pooled to help with performance, so its properties are nullified right after executing the event handler, this makes the value of event.currentTarget null. Event pooling was dropped in React 17 and the normal browser behaviour takes effect; the value of event.currentTarget is non-nullish only when the event is being handled. So that behaviour of event.currentTarget makes it null when you console.log

Bonus

To access the underlying original browser event in React, use the event.nativeEvent An interesting event to also consider is the beforeinput, might be a perfect alternative to focus & keydown events, depending on the use case.

PS

The said OTP component, and maybe the articleʼs title is a little bit clickbaity, I donʼt know.