Open In App

Implementing JOI Module in ReactJS

Last Updated : 03 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Validating user input is an essential part of building robust and secure web applications. JOI is a powerful validation library that helps you define and enforce validation rules for your data.

Prerequisites

  • React JS
  • NPM & Node.js

Approach

Implementing the JOI module in React JS for form validation includes the validation schema according to which the data is validated and to show error and other form styling we will use the bootstrap classes and styling

Joi module is a popular module for data validation. This module validates the data based on schemas. There are various functions like optional(), required(), min(), max(), etc which make it easy to use and a user-friendly module for validating the data.

Advantages of Using JOI over Javascript validations: 

  • It’s easy to get started and easy to use.
  • It is a widely used and popular module for data validation.
  • It supports schema-based validation.

Steps to create React Application

Step 1: Create a react app using the following command.

npx create-react-app my-first-app

Step 2:Move to the project directory by executing the command :

cd my-first-app

Step 3: Install the necessary dependencies. Go to the directory ‘src’ and execute command prompt there and run command

npm install joi-browser bootstrap

Project Structure 

The updated dependencies in package.json file will look like:

"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"bootstrap": "^5.3.2",
"joi": "^17.11.0",
"joi-browser": "^13.4.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}

The react customer form will follow the following schema:

Field Name Validations
First Name minimum length=1 maximum length=2 required
Last Name required
Email required
PIN Code in range 1000-9999

Example: Created a customer form with JOI validation using above schema.

Javascript




// Filename - App.js
 
import ValidationJoiHome from "./ValidationJoi/ValidationJoiHome";
 
function App() {
    return (
        <div className="App">
            <ValidationJoiHome />
        </div>
    );
}
 
export default App;


Javascript




// Filename - ValidationJoi/ValidationJoiHome.js
 
import React from "react";
import CustomerForm from "./CustomerForm";
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap/dist/js/bootstrap.bundle.min";
 
function ValidationJoiHome() {
    return (
        <div>
            <h1 className="text-success">
                GeeksforGeeks: Validation Joi Home
            </h1>
            <CustomerForm />
        </div>
    );
}
export default ValidationJoiHome;


Javascript




// Filename - ValidationJoi/CustomerForm.js
 
import React, { useState } from "react";
import Joi from "joi-browser";
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap/dist/js/bootstrap.bundle.min";
function CustomerForm(props) {
    const [customer, setCustomer] = useState({
        firstName: "",
        lastName: "",
        email: "",
        pin: 0,
    });
 
    const [errors, setErrors] = useState({});
    const schema = {
        firstName: Joi.string().min(1).max(20).required(),
        lastName: Joi.string().required(),
        email: Joi.string().email().required(),
        pin: Joi.number().min(1000).max(9999).required(),
    };
 
    const validateForm = (event) => {
        event.preventDefault();
        const result = Joi.validate(customer, schema, {
            abortEarly: false,
        });
        console.log(result);
        const { error } = result;
        if (!error) {
            return alert("data saved");
        } else {
            const errorData = {};
            for (let item of error.details) {
                const name = item.path[0];
                const message = item.message;
                errorData[name] = message;
            }
            console.log(errors);
            setErrors(errorData);
            return errorData;
        }
    };
 
    const handleSave = (event) => {
        const { name, value } = event.target;
        let errorData = { ...errors };
        const errorMessage = validateProperty(event);
        if (errorMessage) {
            errorData[name] = errorMessage;
        } else {
            delete errorData[name];
        }
        let customerData = { ...customer };
        customerData[name] = value;
        setCustomer(customerData);
        setErrors(errorData);
    };
 
    const validateProperty = (event) => {
        const { name, value } = event.target;
        const obj = { [name]: value };
        const subSchema = { [name]: schema[name] };
        const result = Joi.validate(obj, subSchema);
        const { error } = result;
        return error ? error.details[0].message : null;
    };
    const clearState = () => {
        setCustomer({
            firstName: "",
            lastName: "",
            email: "",
            pin: 0,
        });
    };
    return (
        <div>
            <h3>Add Customer</h3>
            <hr />
            <form className="ui form">
                <div className="form-group">
                    <label>First Name</label>
                    <input
                        type="text"
                        name="firstName"
                        className="form-control"
                        value={customer.firstName}
                        onChange={handleSave}
                    />
                </div>
                {errors.firstName && (
                    <div className="alert alert-danger">
                        {errors.firstName}
                    </div>
                )}
                <div className="form-group">
                    <label>Last Name</label>
                    <input
                        type="text"
                        name="lastName"
                        className="form-control"
                        value={customer.lastName}
                        onChange={handleSave}
                    />
                </div>
                {errors.lastName && (
                    <div className="alert alert-danger">
                        {errors.lastName}
                    </div>
                )}
                <div className="form-group">
                    <label>Email</label>
                    <input
                        type="email"
                        name="email"
                        className="form-control"
                        value={customer.email}
                        onChange={handleSave}
                    />
                </div>
                {errors.email && (
                    <div className="alert alert-danger">
                        {errors.email}
                    </div>
                )}
                <div className="form-group">
                    <label>PIN</label>
                    <input
                        type="number"
                        name="pin"
                        className="form-control"
                        value={customer.pin}
                        onChange={handleSave}
                    />
                </div>
 
                <div className="btn">
                    <button
                        type="submit"
                        onClick={validateForm}
                        className="btn btn-success"
                    >
                        Add customer
                    </button>
                </div>
            </form>
        </div>
    );
}
 
export default CustomerForm;


Step to run the application: Open the terminal and type the following command.

npm start

Output: This output will be visible on the httml://localhost:3000/ on the browser window.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads