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’)” />
When do we expect the string changed to appear in the console?
- After a user presses a key?
- After the user changes focus from the input element? ✅
- After the last key is pressed?
React's onChange
prop
<input type=“text” onChange={() => console.log(‘changed’) />} />
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’)” />
React's onInput
prop
<input type=“text” onInput={() => console.log(‘changed’) />} />
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. 👀
Top comments (0)