Form Validation in React

Before we just start you can take a look at the app running here OR take a look at the code on GitHub OR see the demo here!

GIF Demo

So you want to do form validation in React? But didn’t find any great simple resource for doing this? Want pro-type validation that works like a charm?

So this article is definitely for you, hold on with me to build a great little application🎯

Cover Image

1. Set React App and Packages:

We will be using create-react-app for making a React application. Let’s just create a new React app using:

$ npm install -g create-react-app
$ create-react-app form-validation-react

Run the app

$ cd form-validation-react/
$ npm start

This will open our newly created app on http://localhost:3000/

We will use the following packages that will help us achieve our goal, though they are not mandatory

  • Bootstrap
  • Validator.js
  • classnames

Now, let’s grab these packages real quick

$ npm install bootstrap validator classnames

2. Create Validation Rules:

Create a file Validation.js in src/ directory of the application. This file will be responsible for validating our form fields. Let’s quickly see the file’s contents.


The above file exports the instance of a class that contains methods to validate our fields. We can import this instance of class anywhere and call its methods like validateFields.validateEmail('email_to_validate_goes_here’) to check if the email is valid or not.

Also, read

3. Setting up the Form Component:

Now, we’ve set up our validation rules. Let’s create a component Form.js that will contain our form. We will start by just making a class-based React Component as:

Form.js (starter)

At the top, we’re importing validateFields which is the instance of our validation rules class in Validation.js. The state for this component contains fields for each input in our form with some properties like value and error for that field.

The markup for our Form

I’ve put the form inside a bootstrap card just to make the form look better. When the user submits the form, an event handleSubmit is triggered which validates all the fields and submits the form. Then we’ve two inputs one for email and one for the password.

The input boxes are given a class name form-control which is a bootstrap class for input tag styling. The input tag has two conditional class names is-valid and is-invalid. The is-valid class is given when there is no error for that field and is-invalid class is given when there is an error for that field. Note these two class names are coming from bootstrap and they just change the border of the input to red if it’s invalid and green if it’s valid. The input tags are also given onChange and onBlur event handlers with the validation function passed as an argument. We will explore these event handlers in detail later in this tutorial. After the input tag there is a div with a class name invalid-feedback that just displays the field’s error message.

The submit button for the form has given onMouseDown event handler that updates a property submitCalled in the state of our component to true. We will see why we are doing this when I explain other event handlers.

Event Handlers

Now, the last thing missing in our component is event handlers. Let’s add them to complete Form.js component.

Form.js (complete)

Here we have three event handlers handleBlur, handleChange and handleSubmit. Let’s explore them one-by-one.


This method is triggered when an input box loses focus. It does the following things:

  • First, we get the field from which the focus is loosed using
  • Next, we check if validateOnChange for that field is false because we don’t want the field to be validated on blur if it’s already being validated by onChange.
  • We’re also checking if the submitCalled is false. Here comes the time to explain onMouseDown event handler given to the submit button. The reason why we are assigning mouse down event to submit button and updating submitCalled to true in the state is that when a field is focused and user clicks the submit button, two events trigger onBlur and onSubmit where onBlur is called before onSubmit which causes the onSubmit to not work properly because both the event handlers are updating the state. We don’t want the onBlur event handler to do anything when the form is being submitted that’s why we’re checking if submitCalled is false before doing anything in onBlur.
  • If the above conditions are fulfilled, then we set validateOnChange property for that field to true and error to whatever is returned by our validation method (either error message or false).


This method triggers when the value of an input field is changed. It is pretty simple and does the following:

  • Updates the value in the state for that field.
  • Checks for error if validateOnChange is true for that field.


handleSubmit is triggered when the form is submitted. Our approach in this method is to validate all the fields of our form, if anyone of the field is not valid then prevent the form submission and update the error message for that field in the state.

  • First, we are passing the values of email and password to our validation methods and storing the results in separate variables
  • Then we are evaluating the results returned by the validation methods to check if all the error results are false using JavaScript high order function every.
  • If there are no errors then we submit the form else the state is updated with errors.

4. Import Form Component in App.js:

YES! We did it, hope you survived step 3 😂. I know it was a lot but it definitely worth it. Now we just need to import and render our Form.js component in App.js just like this:


5. Add CSS: (Optional)

To make your application look same as mine you need to replace your App.css with this:

.App {
display: flex;
align-items: center;
height: 100vh;
background-color: #282c34;
.App-content {
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.App-logo {
animation: App-logo-spin infinite 20s linear;
width: 6rem;
margin-top: -1.5rem;
margin-bottom: 1.5rem;
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
to {
transform: rotate(360deg);


The validation procedure is pretty simple but very effective. You can optimize the code further for scalability. I have used bootstrap for making the input boxes red/green according to their error status but you are not bound to use bootstrap. You can define your own stylesheet for doing this, just make it as you feel comfortable.

Feel free to comment if you find anything wrong or write if something can be changed to make it easier.

Trying to make things simple! —

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store