How to validate a radio button in React
You may need to validate a radio button when you are creating a form in React. Just as we have created a common component for the select field and input field in the previous article, here we will create a component for the radio button in React.
Checkout more articles on ReactJS
Demo Application
Steps to validate a radio button in React
1. Create a common component
Let’s create a reusable radio component using Bootstrap where we will pass all required fields.
Same as the Input component and Select component, we have to go through a few more props to handle the validation such as isReq
, errorMsg
, onValidateFunc
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | import React, { memo } from 'react'; import PropTypes from 'prop-types'; const changeHandler = (e, props) => { let value = e.target.value; props.onChangeFunc(value, props.name, e); if (!props.onValidateFunc) return; let msg = null; if (!value && props.isReq) { msg = `Please select ${props.title}.`; } props.onValidateFunc(msg, props.name); } const Radio = props => { const inputProps = { type: "radio", name: props.name, className: props.className } return ( <div className={props.outerClassName}> <label className="form-label">{props.title}</label> <div> {props.options.map((x, i) => <div key={i} className={`form-check${props.isVertical ? '' : ` form-check-inline`}`}> <input {...inputProps} id={x.value} value={x.value} onChange={e => changeHandler(e, props)} /> <label className="form-check-label" htmlFor={x.value}> {x.label} </label> </div>)} </div> {props.errorMsg && <span className="text-danger">{props.errorMsg === true ? `Please select ${props.title}.` : props.errorMsg}</span>} </div> ) } Radio.defaultProps = { name: '', title: '', className: 'form-check-input', outerClassName: 'mb-2', isVertical: false, value: '', options: [], onChangeFunc: () => { }, isReq: null, onValidateFunc: () => { } } Radio.propTypes = { name: PropTypes.string, title: PropTypes.string, className: PropTypes.string, outerClassName: PropTypes.string, isVertical: PropTypes.bool, value: PropTypes.any, options: PropTypes.array, onChangeFunc: PropTypes.func, isReq: PropTypes.bool, errorMsg: PropTypes.any, onValidateFunc: PropTypes.func } export default memo(Radio); |
2. Create a form using the Radio component
Now it’s time to use the Radio component in the main component for gender and status selection. In the first place, we have to define two different state variables called form
and error
.
Let’s define the object for each property in an error state. The error object contains the following attributes.
isReq
– For require validationerrorMsg
– To render the error message on the screenonValidateFunc
– Function to handle the validation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | const [form, setForm] = useState({ gender: null, status: null }); const onValidate = (value, name) => { setError(prev => ({ ...prev, [name]: { ...prev[name], errorMsg: value } })); } const [error, setError] = useState({ gender: { isReq: true, errorMsg: '', onValidateFunc: onValidate }, status: { isReq: true, errorMsg: '', onValidateFunc: onValidate } }); const onHandleChange = useCallback((value, name) => { setForm(prev => ({ ...prev, [name]: value })); }, []); |
Use the following HTML to render the form in React component.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <div className="app"> <div className='mb-3'><strong>Validate a radio button in React - <a href="https://www.cluemediator.com" target="_blank" rel="noreferrer noopener">Clue Mediator</a></strong></div> <div className='form'> <Radio name="gender" title="Gender" value={form.gender} options={genderList} onChangeFunc={onHandleChange} {...error.gender} /> <Radio name="status" title="Status" isVertical={true} value={form.status} options={statusList} onChangeFunc={onHandleChange} {...error.status} /> <button className='btn btn-primary btn-sm mt-2' onClick={handleSubmit}> Submit </button> </div> </div> |
Let’s merge all code together and see how it looks.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | import React, { useState, useCallback } from 'react'; import Radio from './Radio'; const genderList = [ { value: "male", label: "Male" }, { value: "female", label: "Female" }, { value: "other", label: "Other" } ]; const statusList = [ { value: "active", label: "Active" }, { value: "inactive", label: "Inactive" } ]; function App() { const [form, setForm] = useState({ gender: null, status: null }); const onValidate = (value, name) => { setError(prev => ({ ...prev, [name]: { ...prev[name], errorMsg: value } })); } const [error, setError] = useState({ gender: { isReq: true, errorMsg: '', onValidateFunc: onValidate }, status: { isReq: true, errorMsg: '', onValidateFunc: onValidate } }); const onHandleChange = useCallback((value, name) => { setForm(prev => ({ ...prev, [name]: value })); }, []); const validateForm = () => { let isInvalid = false; Object.keys(error).forEach(x => { const errObj = error[x]; if (errObj.errorMsg) { isInvalid = true; } else if (errObj.isReq && !form[x]) { isInvalid = true; onValidate(true, x); } }); return !isInvalid; } const handleSubmit = () => { const isValid = validateForm(); if (!isValid) { console.error('Invalid Form!'); return false; } console.log('Data:', form); } return ( <div className="app"> <div className='mb-3'><strong>Validate a radio button in React - <a href="https://www.cluemediator.com" target="_blank" rel="noreferrer noopener">Clue Mediator</a></strong></div> <div className='form'> <Radio name="gender" title="Gender" value={form.gender} options={genderList} onChangeFunc={onHandleChange} {...error.gender} /> <Radio name="status" title="Status" isVertical={true} value={form.status} options={statusList} onChangeFunc={onHandleChange} {...error.status} /> <button className='btn btn-primary btn-sm mt-2' onClick={handleSubmit}> Submit </button> </div> </div> ); } export default App; |
3. Output
Run the application and check the output in the browser.
I hope you find this article helpful.
Thank you for reading. Happy Coding..!! 🙂