DEV Community

Ezell Frazier
Ezell Frazier

Posted on

When is onChange not the same as onChange?

A colleague raised a fair question, why doesn’t an input element's onchange event type behave the same as React’s onChange?

Wait, what do you mean?, was my initial thought not realizing the inherent difference between the two.

Digging deeper into the question uncovered what could be a jarring experience for a developer.

What we’d expect?🤔

The native web API onchange attribute

<input type=“text” onchange=“console.log(‘changed’)” />
Enter fullscreen mode Exit fullscreen mode

When do we expect the string changed to appear in the console?

  1. After a user presses a key?
  2. After the user changes focus from the input element? ✅
  3. After the last key is pressed?

React's onChange prop

<input type=text onChange={() => console.log(changed) />} />
Enter fullscreen mode Exit fullscreen mode

I think we know what happens here.

The string appears in the console each time the user inputs a new value.

The two event types behave differently by design.

The React team believes this is how the native onchange should behave.

Whenever the element's value has changed, the corresponding event should fire.

But wait, don't we already have an event type for that?

The input event

The native web API oninput attribute

<input type=“text” oninput=“console.log(‘changed’)” />
Enter fullscreen mode Exit fullscreen mode

React's onInput prop

<input type=text onInput={() => console.log(changed) />} />
Enter fullscreen mode Exit fullscreen mode

Here, both React and the web API behave the same, or as we'd expect. The string appears in the console when the user changes the element's value.

So, shouldn't we leverage onInput instead of onChange? Well, that's likely the way to go if one's working with other JSX-based frameworks.

When onChange isn't onChange?

Stencil.js is a neat framework for building web components. Like React, Stencil uses JSX for markup. And if we wanted to use React's onChange behavior, we'd instead need to use onInput.

Solid.js, a newer web framework which draws inspiration from React, can also use JSX for markup. And like Stencil.js, onChange behaves like the native web implementation.

So, if one were to migrate some JSX from one framework to another, note that React's subtle opinion may not carry over.

oninput may also be a good choice if one wants to avoid the onchange trap altogether. 👀

Latest comments (0)