A Brief introduction of Validation in ReactJS

Posted By Damini Sharma | 30-Jul-2018

How to use and Create React Project:-

We’ll use and create-react-app to get  and running quickly with a simple React application.

 

Install the package from npm which is Node Package Manager and create a new application:-

Commands :-

1. $ npm install -g create-react-app


2. $ create-react-app react-form-validation

 

Now let’s run the application:-

Commands:-

$ cd react-form-validation

$ npm start


That opens in:-

http://localhost:3000/ where our new app is running.

In next step, Let’s add bootstrap so that we can style our form easily:-

$ npm install react-bootstrap — save

$ npm install bootstrap@3 — save

 

Import Bootstrap, CSS and optionally Bootstrap theme and CSS also in the beginning of the src/index.js file:-

import ‘bootstrap/dist/css/bootstrap.css’;
 

import ‘bootstrap/dist/css/bootstrap-theme.css’;

Now, let’s build the core of our demo Application. Let’s add a Form component to use forms in our Application.

 

In src/App.js file, Let’s replace the default intro text markup with a Form component that we’re going to build. We also need to import it:-

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Form from './Form.js';class App extends Component {
  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Form Validation</h2>
        </div>
        <Form />
      </div>
    );
  }
}export default App;

Now, let’s create that, Form component in our src/Form.js file.

We’ll make a simple sign up Form Which have Email and Password input fields and a submit button.

import React, { Component } from react;
import ./Form.css;class Form extends Component {
 render () {
   return (
     <form className=Form>
       <h2>Sign up</h2>
       <div className=form-group>
         <label htmlFor=email>Email address</label>
         <input type=email className=form-control
           name=email />
       </div>
       <div className=form-group>
         <label htmlFor=password>Password</label>
         <input type=password className=form-control
           name=password />
       </div>
       <button type=submit className=btn btn-primary>
          Sign up
       </button>
     </form>
   )
 }
}
export default Form;


Now, we initialise the state in the constructor:-

constructor (props) {
  super(props);
  this.state = {
    email: '',
    password: ''
  }
}

We’re setting Email and Password to Empty strings in our js file.

We’ll hook up the Form input fields to these state values, for mail and Password:-

value={this.state.email}

and for password:

value={this.state.password}

But, we’re not updating the state on user inputs. so, if we type in the Form fields. Now, our text won’t appear.

We need an onChange handler for the input fields in our Application:-

onChange={(event) => this.handleUserInput(event)}

That, we’ll define as like that:-

handleUserInput (e) {
  const name = e.target.name;
  const value = e.target.value;
  this.setState({[name]: value});
}

Now, let’s get to the validation on Form inputs.

We’ll have to save any validation errors and the validity status of the Form in the state.

So, Let’s add couple of properties to our initial state in our Form:-

constructor (props) {
  super(props);
  this.state = {
    email: '',
    password: '',
    formErrors: {email: '', password: ''},
    emailValid: false,
    passwordValid: false,
    formValid: false
  }
}

We’re adding a property called formErrors which will be an object with the input fields names as keys and any validation errors as having their values. The initial value for each key is an empty string after that define it.

We also have three boolean properties :-  

First is emailValid, Second is passwordValid and Third is formValid, which we’ll use to enable or disable the form submit button, based on our validation results. We set their initial values to false. after check their Validation it's values change false into true.

Now let’s add a new component called FormErrors for Show any errors from our validation above the form.

<div className=panel panel-default>
 <FormErrors formErrors={this.state.formErrors} />
</div>

This is a very simple example of validation. having  hard-coded field names in our validation code, which is not ideal or scalable. We can also have one validation per field, which is also not practical.

Now, We’ll save it in our src/FormErrors.js file:-

import React from react;

export const FormErrors = ({formErrors}) =>
  <div className='formErrors'>
    {Object.keys(formErrors).map((fieldName, i) => {
      if(formErrors[fieldName].length > 0){
        return (
          <p key={i}>{fieldName} {formErrors[fieldName]}</p>
        )        
      } else {
        return '';
      }
    })}
  </div>

It is a stateless functional component. Now, we’ll call  validation after the user type in the fields like email and password.

The setState method takes  callback function as a second argument, so let’s pass a validation function to it.

handleUserInput (e) {
  const name = e.target.name;
  const value = e.target.value;
  this.setState({[name]: value}, 
                () => { this.validateField(name, value) });
}

Let’s define ValidateField Function or method:-

validateField(fieldName, value) {
  let fieldValidationErrors = this.state.formErrors;
  let emailValid = this.state.emailValid;
  let passwordValid = this.state.passwordValid;

  switch(fieldName) {
    case 'email':
      emailValid = value.match(/^([\w.%+-]+)@([\w-]+\.)+([\w]{2,})$/i);
      fieldValidationErrors.email = emailValid ? '' : ' is invalid';
      break;
    case 'password':
      passwordValid = value.length >= 6;
      fieldValidationErrors.password = passwordValid ? '': ' is too short';
      break;
    default:
      break;
  }
  this.setState({formErrors: fieldValidationErrors,
                  emailValid: emailValid,
                  passwordValid: passwordValid
                }, this.validateForm);
}

validateForm() {
  this.setState({formValid: this.state.emailValid && this.state.passwordValid});
}

We have two different checks for the input fields. For the email field, we check it's  regular expression according to require format or pattern to see if it’s an email. For the password field, we check if the length is a minimum of 6 characters or not.and we applied custom patterns and format of email and password fields.

When the fields don’t pass the check, we set an error message for it and set it's validity to false. and when the field pass the check, we set an success message for it and set it's validity to true.

Then, we call setState to update the formErrors and the field validity and we can pass the validateForm callback to set the value of formValid.

Now, Let's set the disabled attribute of the submit button based on the value of the formValid state property in our application.

<button type="submit" className="btn btn-primary" 
  disabled={!this.state.formValid}>Sign up</button>

So that, our basic form validation works.

We can add one little enhancement by highlighting the input fields when they have an error occured.

We’ll add the bootstrap error class to field’s form-group based on its error value:-

<div className={`form-group
                 ${this.errorClass(this.state.formErrors.email)}`}>
errorClass is a method we can define as:

errorClass(error) {
   return(error.length === 0 ? '' : 'has-error');
}

Now, when a field has an error and we'll entered wrong password, it has a red border around it.

 

 

 

 

 

Request for Proposal

Recaptcha is required.

Sending message..