Form Validation Tutorial with React.JS

React.js is a fantastic user interface primarily library because the user’s view updates automatically when a state changes. This ability to show changes to the user quickly also makes it a good fit for user-facing form errors. React allows you to easily display errors as the form is being filled so the user doesn’t have to fill in the entire form, press the submit button, then try to figure out what they got wrong.

This does not mean React can be used to make a form secure. Hackers can bypass your React form altogether, passing variables directly to the server. You will still have to provide security and additional error-handling on the server side. Using React for error-checking is mainly for making a form easier to use.

We are going to create a simple donation form in our example. The code shows a few places where additional functionality can be added, but we are only going to focus on error-checking in this tutorial.

Download the source code

You may download all the files associated with this tutorial from here.

Learn React online

If you are keen to learn React from the ground-up feel free to check Learn and Understand React JS on Zenva Academy which covers all the basics + lots of bonus topics like React Router and Flux.

Tutorial requirements

  • You must have beginner’s knowledge of React.js, and at least a beginner’s knowledge of JavaScript. If you need to know the basics, check out my previous React tutorial.
  • You will need to download the React library in order to use React on a server and go beyond the testing phase. We show you how to get around this during testing.
  • You will need to download a text editor of some sort. Notepad++ is popular on Windows, and TextMate is popular on Mac machines. An editor that highlights code is preferable.
  • In order to use React as part of a full website, it will need to be incorporated into a larger application. When testing the basic code with external data files, you will need to use a local or remote web server in order to get the page to work. MAMP is a good one for the Mac, and WAMP is most the most common server used on Windows machines. For a complete solution, a Node.js server is one of the most popular servers to use with React. The React library download page (above) also includes a server and other options.

Getting started with the tutorial

There are all sorts of download options for React, but we’re just going to use React from a CDN. React is available from more than one CDN, but here are the most popular links:

We are going to add a couple more JavaScript files to our index.html file:

The babel-core browser.min.js file allows us to use JSX, which will greatly simplify our code. Please see my other React.js tutorial for more on why React is better with JSX. Since this is a form, we are also including jquery, which will make form submission much easier. We don’t actually make much use of it in the code, other than an example submission function. Lastly, we include the Classnames library, which is a teeny file that makes combining class names easier.

Finally, we call our example.js script, which is where all the action takes place. Just be sure to put “text/babel” in your script type so you can make use of JSX in your code.

Now let’s dig into the code:

Setting up for form submission

The ReactDOM.render call at the bottom of the code is the first call that starts the app. We use XML-style JSX to call the DonationBox component. This component doesn’t do much at the moment, but provides a few examples of some of the additional things you can do with React besides error-checking. For example, you could show new donations as they are made, polling the server for new ones. I’ve also included some jquery ajax for an example of how the final form submission can be handled.

The real action starts in the DonationForm component:

Creating abstract form elements

The DonationForm component is our largest component, because this is where all the other form components are included, and where we do most of our form validation. Let’s take a look:

We save one piece of information (the contributor) for passing to the parent and saving on the server, just as an example. The handleSubmit method shows how you would pass the variable to the parent element when the form is submitted. What we want to focus on, though, is the validation functions and component calls. I decided to include form elements in a rather interesting way to show the power of React. The best examples can be seen in the calls to the TextInput and Radios components.

As you can see, there are two calls to the TextInput component, but with different variables and validation functions included in the attributes (available as props in the child components). We do this because the text input is a reusable component. All you have to do is enter different attributes depending on the results you would like to see. You could even add an attribute that gives a different error message depending on whether the field contains a number or dollar amount (we show an example of this on a different field).

Each TextInput component gets its own validation function, which can be accessed from the component using this.props.validate(value). The component itself doesn’t care what type of validation is going on. It simply calls validate, and the parent component takes care of which validation function is being called.

I’ve also included a commonValidate function as an example of how you could do some basic validation on all form fields. In this case, we use it with the second TextInput component and return true, because we need the validate prop function to exist, but we don’t actually want to validate the second field.

The Radios component is interesting because we are actually passing all of the possible values through in a simple array. We also have an optional text field for adding user-generated text, which has its own validation.

The rest of the components are specific to this donation form, but are separated into new components in order to simplify the DownationForm component code. Let’s take a deeper look at those now.

Creating input fields

One component that will be reused in every form field component is an error message. If we want to validate fields as the user enters them, we need to be able to bring up an error message as they are typing. So, let’s start with that:

This component is very small, but powerful. All we have to do when calling this component is include an error message, and a boolean value that tells the component whether it should be displayed or not. The css file (included in the download) will do the rest.

Now let’s take a look at all of our form field components:

The first one is our InputText component. This component includes some validation based on the props sent from the parent. In this case, we show an error message when there are not enough characters, but we show a different message when the field is empty. Both messages were sent as props. All of this validation occurs while the user is typing. This could be annoying for some fields, but it’s a great example of what is possible.

In addition to the local validation, we also call the parent validation function when the user leaves the field (indicating they are finished with it). You could also do all validation in the parent, or just do local validation. There are many options.

Next up is our Radios component. This component actually doesn’t have any validation unless the optional “addAny” prop is set to true. In that case, an extra radio button is added which will display an “anyValue” text field when selected. This text field gets its own validation function, called through the props sent from the parent.

We also have to handle the appearing and disappearing act of the text field. When the “addAny” radio button is clicked, the text field is displayed. When any other option is selected, it’s hidden. We do this with an onClick attribute, but we have to use “bind” in order to send a variable to our handler function. The variable tells the function whether to show or hide the text field.
Screen Shot 2015-10-28 at 5.16.09 PM

The validation handler for the text field simply calls the parent validation field, and uses that result to determine whether to show the InputError component.

You’ll notice that some of the code looks a bit wonky because there are keys for even the <label> and <br /> tags. This is to prevent errors, because React requires a key for all fields. Since we are sending all the values to the Radios component, we have to traverse a for loop of values. JSX can’t just be placed raw into the for loop, so we push each row of JSX to an array. When we do it this way, the keys aren’t automatically included, so we have to include them in every single tag.

Now let’s take a look at a couple of custom form field components.

Payment validation is beyond the scope of this tutorial, but we’ve included a payment section since donations need a way to donate money! Our Payment component also shows a common example of how payments are accepted. There may be some sort of PayPal button, then an option to fill in payment information directly. This is just a simple example of showing a new section of information when a checkbox is clicked.

Screen Shot 2015-10-28 at 5.16.20 PM

One thing that can be annoying about checkbox toggling is that it can get out of sync. In order to prevent that, we take full control over it. When the credit card fields are toggled off, we ensure that the checkbox is not checked. When they are on, the checkbox is checked.

In the Department component, we have included select options with sub-options, plus an option to put any value. This is somewhat similar to what we’ve done in the previous examples of showing and hiding other fields. The main reason it’s included here is to show how we handle this action in every type of field that gives multiple options. It’s also a good example of how to do sub-options.

Screen Shot 2015-10-28 at 5.16.00 PM

One other thing to note about the select field is the multiple={false} attribute. That’s not required, but it’s included here in order to show that it’s possible to have a select field that takes multiple values. When the attribute is set to true, all of the options will be shown in a box rather than appearing as a drop-down. The returning value is then an array.

Questions or Comments?

What did you think of this tutorial? Do you have any questions or comments? What else would you like me to write about? Please let me know in the comments section below.

Published by

Kristen Dyrr

Kristen is a software engineer, tinkerer, podcaster, writer, web developer, and business owner. She has written both entertainment pieces for Yahoo TV and tech pieces for Yahoo Tech. She has her own blog containing gif-tweet-recaps for various TV shows, incorporating animated gifs and humorous fan tweets. She also hosts Red Shirted: The 100 Podcast and Baker Street Podcast for Southgate Media Group. She will also have a small speaking role in the movie Shallow Water, but only if it funds on Kickstarter!

Share this article

Leave a Reply

3 Comments on "Form Validation Tutorial with React.JS"

Notify of
Sort by:   newest | oldest | most voted
Michael Bird

Thanks Kristen for this great implementation of input validation!
In your opinion, is it best to do validation in an entirely React way like above rather than using JQuery Validator? I know this helps for any components going through the render cycle while the user is interacting, but I would think many forms wouldn’t ever need to fire off a render. What do you think?

Damián Aruj

Hey guys, nice implementation!! Here is another solution for react form validations:

Tanguy Krotoff
This article is now a bit outdated. Instead of React.createClass() you should use ES6 classes, see Instead of TextMate and Notepad++ I would recommend Visual Studio Code: Also you use $.ajax from jQuery, I would recommend window.fetch and this polyfill if needed: I’ve created a simple form validation library for React: It takes an approach similar to Angular’ ng-messages and React Router v4 API: Should be at least 5 characters long !/d/.test(value)} warning>Should contain numbers !/[a-z]/.test(value)} warning>Should contain small letters !/[A-Z]/.test(value)} warning>Should contain capital letters !/W/.test(value)} warning>Should contain special characters 1234567891011        Should be at least 5… Read more »