React JS Form Validation Example

This is a step-by-step tutorial on form validation in React.js. We will begin with creating a brand new React Application using the create-react-app tool.

Set up React Application

1. Create a new React app

Open your terminal or command prompt and navigate to the directory where you want to create your React app. Run the following command to create a new React app using create-react-app:
npx create-react-app my-app
This command creates a new directory named my-app and sets up a basic React project structure inside it.

2. Navigate into the app directory

Move into the newly created app directory by running the following command:
cd my-app

3. Install Bootstrap using NPM

In the terminal, run the following command to install Bootstrap as a dependency in your project:
$ npm install bootstrap --save

--save option add an entry in the package.json file

Open the src/index.js file and add the following code:

4. Import Bootstrap CSS into your app

Open the src/index.js file in your project's directory. Add the following import statement at the top of the file:

import 'bootstrap/dist/css/bootstrap.min.css';

5. Start the development server

Start the development server by running the following command in the terminal:
npm start
This command starts the development server and opens your React app in the browser. You should now see Bootstrap styles being applied to your app.

Create EmployeeComponent and Design Add Employee Form

Create EmployeeComponent.jsx file and add the following to it:
import React, {useState} from 'react'

const EmployeeComponent = () => {

    const [firstName, setFirstName] = useState('')
    const [lastName, setLastName] = useState('')
    const [email, setEmail] = useState('')

    const navigate = useNavigate();

    const saveEmployee = (e) => {
        e.preventDefault();

        const employee = {firstName, lastName, email}
        
        console.log(employee)
    }

    return (
        <div>
           <br /><br />
           <div className = "container">
                <div className = "row">
                    <div className = "card col-md-6 offset-md-3 offset-md-3">
                    <h2 className = "text-center">Add Employee</h2>
                        <div className = "card-body">
                            <form>
                                <div className = "form-group mb-2">
                                    <label className = "form-label"> First Name :</label>
                                    <input
                                        type = "text"
                                        placeholder = "Enter first name"
                                        name = "firstName"
                                        className = "form-control"
                                        value = {firstName}
                                        onChange = {(e) => setFirstName(e.target.value)}
                                    >
                                    </input>
                                </div>

                                <div className = "form-group mb-2">
                                    <label className = "form-label"> Last Name :</label>
                                    <input
                                        type = "text"
                                        placeholder = "Enter last name"
                                        name = "lastName"
                                        className = "form-control"
                                        value = {lastName}
                                        onChange = {(e) => setLastName(e.target.value)}
                                    >
                                    </input>
                                </div>

                                <div className = "form-group mb-2">
                                    <label className = "form-label"> Email Id :</label>
                                    <input
                                        type = "email"
                                        placeholder = "Enter email Id"
                                        name = "email"
                                        className = "form-control"
                                        value = {email}
                                        onChange = {(e) => setEmail(e.target.value)}
                                    >
                                    </input>
                                </div>

                                <button className = "btn btn-success" onClick = {(e) => saveEmployee(e)} >Submit </button>
                                {/* <Link to="/employees" className="btn btn-danger"> Cancel </Link> */}
                            </form>

                        </div>
                    </div>
                </div>

           </div>

        </div>
    )
}

export default EmployeeComponent

The useState hook is used to define and manage state variables in functional components.

The saveEmployee function is defined to handle the form submission. It prevents the default form submission behavior using e.preventDefault().

Next, import and use EmployeeComponent in an App component:

import './App.css';
import EmployeeComponent from './components/EmployeeComponent';

function App() {
  return (
    <div>
      <EmployeeComponent />
   </div>
  );
}

export default App;

Next, hit this link in the browser: http://localhost:3000/ and you will see the Add Employee form like this:


Next, let's add the validation for the above Add Employee form with Bootstrap CSS classes.

Form Validation

1. Initialize State Variables

Use the useState hook to initialize state variables that will hold validation errors.
    const [errors, setErrors] = useState({
        firstName: '',
        lastName: '',
        email: '',
    });

2. Update Validation Errors

Write a validation function that checks the form data and returns validation errors. This function updates the errors state with the appropriate error messages for each field.
   const validateForm = () => {
        let valid = true;
        //const { name, email, password } = formData;
        const errorsCopy = { ...errors };
    
        if (!firstName.trim()) {
          errorsCopy.firstName = 'First Name is required';
          valid = false;
        } else {
          errorsCopy.firstName = '';
        }
    
        if (!lastName.trim()) {
            errorsCopy.lastName = 'Last Name is required';
            valid = false;
          } else {
            errorsCopy.lastName = '';
        }

        if (!email.trim()) {
          errorsCopy.email = 'Email is required';
          valid = false;
        } else if (!/\S+@\S+\.\S+/.test(email)) {
          errorsCopy.email = 'Email is invalid';
          valid = false;
        } else {
          errorsCopy.email = '';
        }

        setErrors(errorsCopy);
        return valid;
      };

3. Validate Form on Submission

Within submit event handler function, enclose all the logic inside validateForm() method:

    const saveEmployee = (e) => {
        e.preventDefault();
        console.log(validateForm());
        if(validateForm()){
            const employee = {firstName, lastName, email}
            console.log(employee) 
        }        
    }

Note that the valid variable returns a boolean value false if there are any errors.

4. Display Validation Errors

In the JSX code, add logic to conditionally render error messages based on the validation errors state. This can be done by adding an element with appropriate classes (is-invalid and invalid-feedback) and the error message text.

 <form>
        <div className = "form-group mb-2">
            <label className = "form-label"> First Name :</label>
            <input
                type = "text"
                placeholder = "Enter first name"
                name = "firstName"
                className={`form-control ${errors.firstName ? 'is-invalid' : ''}`}
                value = {firstName}
                onChange = {(e) => setFirstName(e.target.value)}
            >
            </input>
            { errors.firstName && <div className="invalid-feedback">{errors.firstName}</div> }
        </div>

        <div className = "form-group mb-2">
            <label className = "form-label"> Last Name :</label>
            <input
                type = "text"
                placeholder = "Enter last name"
                name = "lastName"
                className={`form-control ${errors.lastName ? 'is-invalid' : ''}`}
                value = {lastName}
                onChange = {(e) => setLastName(e.target.value)}
            >
            </input>
            { errors.lastName && <div className="invalid-feedback">{errors.lastName}</div> }
        </div>

        <div className = "form-group mb-2">
            <label className = "form-label"> Email Id :</label>
            <input
                type = "email"
                placeholder = "Enter email Id"
                name = "email"
                className={`form-control ${errors.email ? 'is-invalid' : ''}`}
                value = {email}
                onChange = {(e) => setEmail(e.target.value)}
            >
            </input>
            {errors.email && <div className="invalid-feedback">{errors.email}</div>}
        </div>

        <button className = "btn btn-success" onClick={(e) => saveEmployee(e)}>Submit </button>
        {/* <Link to="/employees" className="btn btn-danger"> Cancel </Link> */}
    </form>

Complete Code

Here is the complete code of EmployeeComponent for your reference:

import React, { useState } from 'react'

const EmployeeComponent = () => {

    const [firstName, setFirstName] = useState('')
    const [lastName, setLastName] = useState('')
    const [email, setEmail] = useState('')

    const saveEmployee = (e) => {
        e.preventDefault();
        console.log(validateForm());
        if(validateForm()){
            const employee = {firstName, lastName, email}
            console.log(employee) 
        }        
    }

    const [errors, setErrors] = useState({
        firstName: '',
        lastName: '',
        email: '',
    });

     const validateForm = () => {
        let valid = true;
        //const { name, email, password } = formData;
        const errorsCopy = { ...errors };
    
        if (!firstName.trim()) {
          errorsCopy.firstName = 'First Name is required';
          valid = false;
        } else {
          errorsCopy.firstName = '';
        }
    
        if (!lastName.trim()) {
            errorsCopy.lastName = 'Last Name is required';
            valid = false;
          } else {
            errorsCopy.lastName = '';
        }

        if (!email.trim()) {
          errorsCopy.email = 'Email is required';
          valid = false;
        } else if (!/\S+@\S+\.\S+/.test(email)) {
          errorsCopy.email = 'Email is invalid';
          valid = false;
        } else {
          errorsCopy.email = '';
        }

        setErrors(errorsCopy);
        return valid;
      };

    return (
        <div>
           <br /><br />
           <div className = "container">
                <div className = "row">
                    <div className = "card col-md-6 offset-md-3 offset-md-3">
                        <h2 className='text-center'>Add Employee</h2>
                        <div className = "card-body">
                            <form>
                                <div className = "form-group mb-2">
                                    <label className = "form-label"> First Name :</label>
                                    <input
                                        type = "text"
                                        placeholder = "Enter first name"
                                        name = "firstName"
                                        className={`form-control ${errors.firstName ? 'is-invalid' : ''}`}
                                        value = {firstName}
                                        onChange = {(e) => setFirstName(e.target.value)}
                                    >
                                    </input>
                                    { errors.firstName && <div className="invalid-feedback">{errors.firstName}</div> }
                                </div>

                                <div className = "form-group mb-2">
                                    <label className = "form-label"> Last Name :</label>
                                    <input
                                        type = "text"
                                        placeholder = "Enter last name"
                                        name = "lastName"
                                        className={`form-control ${errors.lastName ? 'is-invalid' : ''}`}
                                        value = {lastName}
                                        onChange = {(e) => setLastName(e.target.value)}
                                    >
                                    </input>
                                    { errors.lastName && <div className="invalid-feedback">{errors.lastName}</div> }
                                </div>

                                <div className = "form-group mb-2">
                                    <label className = "form-label"> Email Id :</label>
                                    <input
                                        type = "email"
                                        placeholder = "Enter email Id"
                                        name = "email"
                                        className={`form-control ${errors.email ? 'is-invalid' : ''}`}
                                        value = {email}
                                        onChange = {(e) => setEmail(e.target.value)}
                                    >
                                    </input>
                                    {errors.email && <div className="invalid-feedback">{errors.email}</div>}
                                </div>

                                <button className = "btn btn-success" onClick={(e) => saveEmployee(e)}>Submit </button>
                                {/* <Link to="/employees" className="btn btn-danger"> Cancel </Link> */}
                            </form>

                        </div>
                    </div>
                </div>

           </div>

        </div>
    )
}

export default EmployeeComponent

Test Form Validation

Refresh the React App in the browser and click on Submit button, you will see the below result:

Related Tutorials

Comments