Table of Contents
In JavaScript, you might have come across onchange
and onblur
events.
In React, they behave slightly differently.
In this article, we will see what is the difference and how to use onChange
and onBlur
events in React for text inputs.
onchange and onblur events in JavaScript
Consider the following example in JavaScript:
1<!DOCTYPE html>2<html>3 <head>4 <title>onBlur and onChange</title>5 <meta charset="UTF-8" />6 </head>78 <body>9 <div id="app">10 <input onchange="changeHandler(this.value)" onblur="blurHandler()" />11 </div>12 </body>13 <script>14 function changeHandler(value) {15 console.log("value changed: ", value)16 }17 function blurHandler() {18 console.log("input blurred")19 }20 </script>21</html>
We have a text input, and 2 events (onchange and onblur) bound to it. If you run the example in the Code Sandbox and open the console, you will see that:
- The
blurHandler
will be called every time you focus out of the text input. - The
changeHandler
will be triggered only when you change something and focus out of the text input. It will not be triggered while you are typing something. In the next section, we will see how it is handled differently in React.
onchange and onblur events in React
Here, we have converted the above JavaScript example to React:
1function App() {2 const changeHandler = e => {3 console.log("value changed: ", e.target.value)4 }56 const blurHandler = () => {7 console.log("input blurred")8 }910 return (11 <div>12 <input13 placeholder="Enter email"14 onChange={changeHandler}15 onBlur={blurHandler}16 />17 </div>18 )19}2021export default App
If you open the browser console and test the below input,
you will see that onChange
event will be triggered on every keypress.
If you are browsing through mobile (or too lazy to open the browser console 😜), this is how the logs will look:
So the main difference between onChange
event in JavaScript and React is that
in JavaScript it will be triggered only when the user focuses out (after changing the text).
However, in React onChange
event will be triggered as soon as the user changes the text without waiting for the user to focus out.
Another obvious difference is that onChange
in React is camel-cased.
If you use all small cases, then you would get the following warning in the browser console and the functionality wouldn't work:
Invalid event handler property `onchange`. Did you mean `onChange`?
Combining onBlur and onChange to validate the input
In one of my previous articles, I have written about form validation in React in depth.
Here we will be focusing on just the email field validation using onBlur
and onChange
events.
Consider the following code:
1import { useState } from "react"23function App() {4 const [email, setEmail] = useState({5 value: "",6 hasError: false,7 })89 const changeHandler = e => {10 console.log("value changed: ", e.target.value)11 const inputValue = e.target.value.trim().toLowerCase()12 let hasError = false13 if (14 !/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(15 inputValue16 )17 ) {18 hasError = true19 }20 setEmail(currentValue => ({21 ...currentValue,22 value: e.target.value,23 hasError,24 }))25 }2627 return (28 <div>29 <input30 placeholder="Enter email"31 value={email.value}32 onChange={changeHandler}33 />34 {email.hasError && <div>Please enter a valid email</div>}35 </div>36 )37}3839export default App
Here as soon as the user starts typing, we are checking if the input is valid or not and showing the error message. You can check yourself in the below input:
This might not be a great user experience, since the user would want them to finish typing before they are told they have inputted incorrect data.
This is when onBlur
event comes handy. See the updated code below:
1import { useState } from "react"23function App() {4 const [email, setEmail] = useState({5 value: "",6 hasError: false,7 touched: false,8 })910 const changeHandler = e => {11 console.log("value changed: ", e.target.value)12 const inputValue = e.target.value.trim().toLowerCase()13 let hasError = false14 if (15 !/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(16 inputValue17 )18 ) {19 hasError = true20 }21 setEmail(currentValue => ({22 ...currentValue,23 value: e.target.value,24 hasError,25 }))26 }2728 const blurHandler = () => {29 console.log("input blurred")30 setEmail(currentValue => ({31 ...currentValue,32 touched: true,33 }))34 }3536 return (37 <div>38 <input39 placeholder="Enter email"40 value={email.value}41 onChange={changeHandler}42 onBlur={blurHandler}43 />44 {email.touched && email.hasError && <div>Please enter a valid email</div>}45 </div>46 )47}4849export default App
We have introduced a new property in the state called touched
,
which will be updated to true only when the user focuses out the text input.
You can verify in the below input that the error message is displayed only after you focus out the text box.
That's it in this article. If you have any queries, ask them in the comments below!
Do follow me on twitter where I post developer insights more often!