How to Add Form Validation in React using React useRef() Hook ?
Published: 2023-01-21 12:16:54

[Go For Live Demo](https://biharisoft.com/EduBoxLive/FormValidationInReactHook)

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>



        </>
```

**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;
}
```
**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:''
}
```

**_Create Array of List For Our Drop-Down List._**

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

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

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

**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;
```

**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 }))

        }

    }
```

**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;
    }

```

**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')
        }
       

    }
```


**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;
```

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

**_Reference [w3schools](https://www.w3schools.com/react/default.asp)_**