How to "onchange" in ReactJS

21 October 2015   27 comments   ReactJS, JavaScript

Mind that age!

This blog post is 5 years old! Most likely, its content is outdated. Especially if it's technical.

Normally, in vanilla Javascript, the onchange event is triggered after you have typed something into a field and then "exited out of it", e.g. click outside the field so the cursor isn't blinking in it any more. This for example

document.querySelector('input').onchange = function(event) {
  document.querySelector('code').textContent =;

First of all, let's talk about what this is useful for. One great example is a sign-up form where you have to pick a username or type in an email address or something. Before the user gets around to pressing the final submit button you might want to alert them early that their chosen username is available or already taken. Or you might want to alert early that the typed in email address is not a valid one. If you execute that kind of validation on every key stroke, it's unlikely to be a pleasant UI.

Problem is, you can't do that in ReactJS. It doesn't work like that. The explanation is quite non-trivial:

*"<input type="text" value="Untitled"> renders an input initialized with the value, Untitled. When the user updates the input, the node's value property will change. However, node.getAttribute('value') will still return the value used at initialization time, Untitled.

Unlike HTML, React components must represent the state of the view at any point in time and not only at initialization time."*

Basically, you can't easily rely on the input field because the state needs to come from the React app's state, not from the browser's idea of what the value should be.

You might try this

var Input = React.createClass({
  getInitialState: function() {
    return {typed: ''};
  onChange: function(event) {
  render: function() {
    return <div>
        <input type="text" onChange={this.onChange.bind(this)}/>
        You typed: <code>{this.state.typed}</code>
React.render(<Input/>, document.querySelector('div'));

But what you notice is the the onChange handler is fired on every key stroke. Not just when the whole input field has changed.

So, what to do?

The trick is surprisingly simple. Use onBlur instead!

Same snippet but using onBlur instead

var Input = React.createClass({
  getInitialState: function() {
    return {typed: ''};
  onBlur: function(event) {
  render: function() {
    return <div>
        <input type="text" onBlur={this.onBlur.bind(this)}/>
        You typed: <code>{this.state.typed}</code>
React.render(<Input/>, document.querySelector('div'));

Now, your handler is triggered after the user has finished with the field.



Thanks for this.


hi jack


didnt work for me


Nice, worked for me. Could you perhaps elaborate on why onBlur works, and what is the actual use case for onBlur? Thank you!

AJ Farkas

Good write-up. You can clean up the code even more by removing `.bind(this)`: `this` always refers to the React component here.


I don't think so. If you don't bind `this`, `this` would be the `` ( the instance of <input> ).
Your case is probably because you always use the ES6 arrow function ( (args)=>{...} ), which treats `this` as a normal variable. This is unlike a classic anonymous "function (args) { ... }".

Sergei Gribovskii

No, that's because React now binding it by itself. So You don't need to use it. And to say more you have to not use it. Not if you need to pass some params for example you need to type .bind(null, param1, param2). Just read the updated documentation of React.


Unless you are Using ES6 syntax where .bind(this) is needed. Using ES5 and older syntax, You do not need to .bind(this).



Thank you, very useful.
There are more wrong ways than there are good ways of using "this". It is ridiculous how simple things can be done the wrong way. Smart people devising new ways for stupids like me to shoot in the leg :-)).


Thanks, It work for me


Thanks a lot , it worked for me


works for me.

Jeveen Shrestha

Thanks, it works for me.

Mike Rehy

saved my form! thanks

Roman Stejskal

Note that the native implementation (at least in Chrome) of `onChange` and `onBlur` is not the same!

`blur` only triggers once you click (or tab) out of the input (when the input loses focus), whereas `change` can also be triggered by hitting the Enter key!

Yacoub Oweis

You are absolutely right about the "Enter key", and this is very important in many cases to maintain a good user experience for the form elements. A simple solution to adopt the behavior of the Enter key is this code snip-it:

<input type="text" onBlur={this.onBlur} onKeyPress={this.handleEnterKeyPress} />

handleEnterKeyPress: function (e) {
        if(e.which == 13){
        return false;

Meow Woof

return false doesn't have an effect here; this isn't jQuery

Andreas Susilo

Thanks. It works!

Spiryt Sista


Anoop John

Thanks... this helped immensely!!




Thanks, was a huge help!


Using **defaultValue** attribute worked for me in case of onblur.

Thuc Tran Van

Thank you so much


onBlur handler should compare content to make sure it really changed.


Ooooo maiiii gooooshhh, didn't realized this, awesomeee man, thanks a lot!

thang thang

this work but it can create a bug, If the user Press Enter, it should handle something, but the input not blur yet and the state still not update then enter action will handle an old state.

Your email will never ever be published

Related posts

And bash basics 16 October 2015
Weight of your PostgreSQL tables "lumped together" 31 October 2015
Related by Keyword:
10 Reasons I Love create-react-app 04 January 2017
How to deploy a create-react-app 04 November 2016
Visual speed comparison of AngularJS and ReactJS 20 July 2015
Careful when dealing with options in IE 14 April 2006