DEV Community

Radheshyam Gupta
Radheshyam Gupta

Posted on • Edited on

How to Add Form Validation in React using React useRef() Hook ?

Go For Live Demo

If you've worked on any react applications React Hook played a big role to Control Html elements and its properties.

Hook Which played a big role for developing React Application are useState(),useEffect(),useRef() and More .

In This post i will work on useState() Hook to Save input Data and useRef() for Form Validation.

Now we Come on Our Topic.

How to Create a Form in React? it is Design Part only

<>
            <div className='FormValBody'>

                <div className='FormValInputLabelSp'><div className='labelSeprater'><label >Name<span className='FormErrorLabelSp'>*</span></label></div>
                    <input ref={(element) => formValidateRef.current[0] = element} type='text' name='Name' value={Name} onChange={(e) => { onInputChange(e) }} />
                </div>



                <div className='FormValInputLabelSp'><div className='labelSeprater'><label >Mobile No<span className='FormErrorLabelSp'>*</span></label></div>
                    <input ref={(element) => formValidateRef.current[1] = element} type='text' name='MobileNo' value={MobileNo} onChange={(e) => { onInputChange(e) }} /></div>


                <div className='FormValInputLabelSp'><div className='labelSeprater'><label >Email Address<span className='FormErrorLabelSp'></span></label></div>
                    <input type='text' name='EmailAddress' value={EmailAddress} onChange={(e) => { onInputChange(e) }} /></div>



                <div className='FormValInputLabelSp'><div className='labelSeprater'><label >Gender<span className='FormErrorLabelSp'>*</span></label></div>
                    <label> Male </label>
                    <input ref={(element) => formValidateRef.current[2] = element} type='radio' name='Gender' value='Male' onChange={(e) => { onInputChange(e) }} />
                    <label> Female </label>
                    <input ref={(element) => formValidateRef.current[3] = element}  name='Gender' type='radio' value='Female' onChange={(e) => { onInputChange(e) }} /></div>



                <div className='FormValInputLabelSp'>
                    <div className='labelSeprater'>
                        <label >Date of Birth<span className='FormErrorLabelSp'>*</span></label>
                    </div>
                    <input ref={(element) => formValidateRef.current[4] = element} type='date' name='DateOfBirth' value={DateOfBirth} onChange={(e) => { onInputChange(e) }} />
                </div>



                <div className='FormValInputLabelSp'><div className='labelSeprater'><label >Language<span className='FormErrorLabelSp'>*</span></label></div>
                    <label>Hindi</label>
                    <input ref={(element) => formValidateRef.current[5] = element} type='checkBox' name='Language' value='Hindi' onChange={(e) => { onInputChange(e) }} />
                    <label>Marathi</label>
                    <input ref={(element) => formValidateRef.current[6] = element}  name='Language' type='checkBox' value='Marathi' onChange={(e) => { onInputChange(e) }} />
                    <label>English</label>
                    <input ref={(element) => formValidateRef.current[7] = element}  name='Language' type='checkBox' value='English' onChange={(e) => { onInputChange(e) }} />
                </div>
                <div className='FormValInputLabelSp'><div className='labelSeprater'><label >Country<span className='FormErrorLabelSp'>*</span></label></div>
                    <label>India</label>
                    <input ref={(element) => formValidateRef.current[8] = element} type='checkBox' name='Country' value='India' onChange={(e) => { onInputChange(e) }} />
                    <label>Nepal</label>
                    <input ref={(element) => formValidateRef.current[9] = element} name='Country' type='checkBox' value='Nepal' onChange={(e) => { onInputChange(e) }} />
                   </div>



                <div className='FormValInputLabelSp'><div className='labelSeprater'><label >State<span className='FormErrorLabelSp'>*</span></label></div>
                    <select ref={(element) => formValidateRef.current[10] = element} name='State' value={State} onChange={(e) => { onInputChange(e) }}>
                        <option value=''>---Select---</option>
                        {StateName.map((sName, index) => (
                            <option key={index + sName} value={sName}>{sName}</option>
                        ))}
                    </select></div>

                <button className='btnAdd' onClick={AddBtnFnt}>Add</button>
            </div>



        </>
Enter fullscreen mode Exit fullscreen mode

Now We Create App.css file for Styling Our Form.

App.css

/*form Validation */

.FormValBody {
    float: left;
    padding: 10px 10px 10px 10px;
    background-color: azure;
}

    .FormValBody input {       
        padding: 5px 5px 5px 5px;
        border-color: gainsboro;
        outline-color: darkgrey;
        font-family: 'Times New Roman';
        font-size: 18px;
    }
.FormValBody input:active{
    outline-color:blue;
}

.FormValInputLabelSp {
    width: 393px;
    margin-top: 7px;
}
.labelSeprater {
    width: 133px;
    display: inline-block;
}

.FormErrorLabelSp {
    font-family: 'Comic Sans MS';
    font-size: 12px;
    color: red;
}

.btnAdd {
    margin-top:25px;
    margin-bottom:15px;
    margin-left: 38%;
    border: none;
    padding: 10px 20px 10px 20px;
    background-color: ButtonFace;
}
.btnAdd:hover{
    cursor:pointer;
}
Enter fullscreen mode Exit fullscreen mode

For Form Validation And Getting input Fields Value ,First We create Model related to our form.
Model For Form

Model Object

const DetailsModel = {
    Name: '',
    MobileNo: '',
    EmailAddress: '',
    Gender: '',
    DateOfBirth: '',
    Language: [],
    State: '',
    Country:''
}
Enter fullscreen mode Exit fullscreen mode

Create Array of List For Our Drop-Down List.

const StateName = ['Assam', 'Bihar', 'Chhattisgarh', 'Jharkhand', 'Karnataka', 'Maharashtra', 'Uttar Pradesh'];
Enter fullscreen mode Exit fullscreen mode

Next We use useState() Hook For Storing Input Data and useRef() HooK for Validate Our Form

const [details, setDetails] = useState(DetailsModel);
 const formValidateRef = useRef([]);
Enter fullscreen mode Exit fullscreen mode

For Easily Access Value Of Our Object Model Key Value, we destructure our Model Object

Deestructuring Object

/* Deestructuring Object*/

    const { Name, MobileNo, EmailAddress, Gender, DateOfBirth, Language, State } = details;
Enter fullscreen mode Exit fullscreen mode

Now We Create a Arrow Function For Update Out Input Field Value State.
onInputChange() function

const onInputChange = (e) => {

        const { name, value } = e.target;

        if (e.target.type === 'checkbox') {

            if (e.target.checked) {

                setDetails((previous) => ({ ...previous, [name]: [...eval(name), value] }));
            }
            else {
                const filterData = eval(name).filter((lang) => { return lang !== value });

                setDetails((previous) => ({ ...previous, [name]: filterData }));
            }
        }

        else {

            setDetails((previous) => ({ ...previous, [name]: value }))

        }

    }
Enter fullscreen mode Exit fullscreen mode

After Storing This all Form Input fields data in state ,Now Time To validate Form. So We Create New Arrow Function for Validation.
ValidateData() function

const ValidateData = () => {
        const validateArray = [];
        const checkedList= [];
        const unCheckedList= [];
        for (let i = 0; i < formValidateRef.current.length; i++) {

            if (!formValidateRef.current[i].value) {

                validateArray.push({ ErrorMsg: formValidateRef.current[i].name + '  is required' });
            }
            else if (formValidateRef.current[i].value) {
                if (formValidateRef.current[i].type === 'checkbox' || formValidateRef.current[i].type === 'radio') {

                    if (formValidateRef.current[i].checked) {
                        checkedList.push({ ErrorMsg: formValidateRef.current[i].name, IsStatus: formValidateRef.current[i].checked });
                    }
                    else {
                        unCheckedList.push({ ErrorMsg: formValidateRef.current[i].name, IsStatus: formValidateRef.current[i].checked });
                    }
                }  

            }
        }


        const checkedDt = [...new Map(checkedList.map((obj) => [obj.ErrorMsg, obj])).values()];
        const unCheckedDt = [...new Map(unCheckedList.map((obj) => [obj.ErrorMsg, obj])).values()];

        const results = unCheckedDt.filter(({ ErrorMsg: unErrorMsg }) => !checkedDt.some(({ ErrorMsg: ckErrorMsg }) => ckErrorMsg === unErrorMsg));


        if (checkedDt.length === 0 && unCheckedDt.length > 0) {
            unCheckedDt.map((data) => {

                validateArray.push({ ErrorMsg: data.ErrorMsg + '  is required' });
            })

        }
        else if (checkedDt.length > 0 && unCheckedDt.length > 0) {

            results.map((data) => {

                validateArray.push({ ErrorMsg: data.ErrorMsg + '  is required' });
            })

        }

        return validateArray;
    }

Enter fullscreen mode Exit fullscreen mode

So Finally We Call This Validation Function On Add Button and And after Validation Of Form ,we Show Data in alert() .
AddBtnFnt()

const AddBtnFnt = () => {

        const isValied = ValidateData();
        if (isValied.length > 0) {

            alert(JSON.stringify(isValied))

        }
        else {
            alert('SuccessFully Added')
        }


    }
Enter fullscreen mode Exit fullscreen mode

Now Finally We Validate Our Form. Final All Code are Below
App.js

import React, { useState } from 'react';
import './App.css';
import React, { useRef, useState } from 'react';

const StateName = ['Assam', 'Bihar', 'Chhattisgarh', 'Jharkhand', 'Karnataka', 'Maharashtra', 'Uttar Pradesh'];

const DetailsModel = {
    Name: '',
    MobileNo: '',
    EmailAddress: '',
    Gender: '',
    DateOfBirth: '',
    Language: [],
    State: '',
    Country:''
}



const App = () => {

    const [details, setDetails] = useState(DetailsModel);

    const formValidateRef = useRef([]);

    /* Deestructuring Object*/

    const { Name, MobileNo, EmailAddress, Gender, DateOfBirth, Language, State, Country } = details;


    const onInputChange = (e) => {

        const { name, value } = e.target;

        if (e.target.type === 'checkbox') {

            if (e.target.checked) {

                setDetails((previous) => ({ ...previous, [name]: [...eval(name), value] }));
            }
            else {
                const filterData = eval(name).filter((lang) => { return lang !== value });

                setDetails((previous) => ({ ...previous, [name]: filterData }));
            }
        }

        else {

            setDetails((previous) => ({ ...previous, [name]: value }))

        }

    }

    const ValidateData = () => {
        const validateArray = [];
        const checkedList= [];
        const unCheckedList= [];
        for (let i = 0; i < formValidateRef.current.length; i++) {

            if (!formValidateRef.current[i].value) {

                validateArray.push({ ErrorMsg: formValidateRef.current[i].name + '  is required' });
            }
            else if (formValidateRef.current[i].value) {
                if (formValidateRef.current[i].type === 'checkbox' || formValidateRef.current[i].type === 'radio') {

                    if (formValidateRef.current[i].checked) {
                        checkedList.push({ ErrorMsg: formValidateRef.current[i].name, IsStatus: formValidateRef.current[i].checked });
                    }
                    else {
                        unCheckedList.push({ ErrorMsg: formValidateRef.current[i].name, IsStatus: formValidateRef.current[i].checked });
                    }


                }



            }


        }



        const checkedDt = [...new Map(checkedList.map((obj) => [obj.ErrorMsg, obj])).values()];
        const unCheckedDt = [...new Map(unCheckedList.map((obj) => [obj.ErrorMsg, obj])).values()];

        const results = unCheckedDt.filter(({ ErrorMsg: unErrorMsg }) => !checkedDt.some(({ ErrorMsg: ckErrorMsg }) => ckErrorMsg === unErrorMsg));


        if (checkedDt.length === 0 && unCheckedDt.length > 0) {
            unCheckedDt.map((data) => {

                validateArray.push({ ErrorMsg: data.ErrorMsg + '  is required' });
            })

        }
        else if (checkedDt.length > 0 && unCheckedDt.length > 0) {

            results.map((data) => {

                validateArray.push({ ErrorMsg: data.ErrorMsg + '  is required' });
            })

        }

        return validateArray;
    }



    const AddBtnFnt = () => {

        const isValied = ValidateData();
        if (isValied.length > 0) {

            alert(JSON.stringify(isValied))

        }
        else {
            alert('SuccessFully Added')
        }


    }


    return (

        <>
            <div className='FormValBody'>

                <div className='FormValInputLabelSp'><div className='labelSeprater'><label >Name<span className='FormErrorLabelSp'>*</span></label></div>
                    <input ref={(element) => formValidateRef.current[0] = element} type='text' name='Name' value={Name} onChange={(e) => { onInputChange(e) }} />
                </div>



                <div className='FormValInputLabelSp'><div className='labelSeprater'><label >Mobile No<span className='FormErrorLabelSp'>*</span></label></div>
                    <input ref={(element) => formValidateRef.current[1] = element} type='text' name='MobileNo' value={MobileNo} onChange={(e) => { onInputChange(e) }} /></div>


                <div className='FormValInputLabelSp'><div className='labelSeprater'><label >Email Address<span className='FormErrorLabelSp'></span></label></div>
                    <input type='text' name='EmailAddress' value={EmailAddress} onChange={(e) => { onInputChange(e) }} /></div>



                <div className='FormValInputLabelSp'><div className='labelSeprater'><label >Gender<span className='FormErrorLabelSp'>*</span></label></div>
                    <label> Male </label>
                    <input ref={(element) => formValidateRef.current[2] = element} type='radio' name='Gender' value='Male' onChange={(e) => { onInputChange(e) }} />
                    <label> Female </label>
                    <input ref={(element) => formValidateRef.current[3] = element}  name='Gender' type='radio' value='Female' onChange={(e) => { onInputChange(e) }} /></div>



                <div className='FormValInputLabelSp'>
                    <div className='labelSeprater'>
                        <label >Date of Birth<span className='FormErrorLabelSp'>*</span></label>
                    </div>
                    <input ref={(element) => formValidateRef.current[4] = element} type='date' name='DateOfBirth' value={DateOfBirth} onChange={(e) => { onInputChange(e) }} />
                </div>



                <div className='FormValInputLabelSp'><div className='labelSeprater'><label >Language<span className='FormErrorLabelSp'>*</span></label></div>
                    <label>Hindi</label>
                    <input ref={(element) => formValidateRef.current[5] = element} type='checkBox' name='Language' value='Hindi' onChange={(e) => { onInputChange(e) }} />
                    <label>Marathi</label>
                    <input ref={(element) => formValidateRef.current[6] = element}  name='Language' type='checkBox' value='Marathi' onChange={(e) => { onInputChange(e) }} />
                    <label>English</label>
                    <input ref={(element) => formValidateRef.current[7] = element}  name='Language' type='checkBox' value='English' onChange={(e) => { onInputChange(e) }} />
                </div>
                <div className='FormValInputLabelSp'><div className='labelSeprater'><label >Country<span className='FormErrorLabelSp'>*</span></label></div>
                    <label>India</label>
                    <input ref={(element) => formValidateRef.current[8] = element} type='checkBox' name='Country' value='India' onChange={(e) => { onInputChange(e) }} />
                    <label>Nepal</label>
                    <input ref={(element) => formValidateRef.current[9] = element} name='Country' type='checkBox' value='Nepal' onChange={(e) => { onInputChange(e) }} />
                   </div>



                <div className='FormValInputLabelSp'><div className='labelSeprater'><label >State<span className='FormErrorLabelSp'>*</span></label></div>
                    <select ref={(element) => formValidateRef.current[10] = element} name='State' value={State} onChange={(e) => { onInputChange(e) }}>
                        <option value=''>---Select---</option>
                        {StateName.map((sName, index) => (
                            <option key={index + sName} value={sName}>{sName}</option>
                        ))}
                    </select></div>

                <button className='btnAdd' onClick={AddBtnFnt}>Add</button>
            </div>



        </>)
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Well done! Finally Validate Our For And Make A Awesome GUI ! Drop some love by liking or commenting ♥

Reference w3schools

Top comments (0)