Form validation in React.js can be done in several ways, ranging from simple client-side validation to using the advanced libraries. Here’s an overview of how to implement basic form validation in React using both traditional methods and with the help of popular libraries.
1. Basic Form Validation in React (Without Libraries)
Here’s an exercise of a simple form validation using React state and events:
Simple Form with Validation
#reactjs
import React, { useState } from 'react';
function MyForm() {
const [formData, setFormData] = useState({
username: '',
email: '',
password: ''
});
const [errors, setErrors] = useState({
username: '',
email: '',
password: ''
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value
});
};
const validate = () => {
const newErrors = {};
if (!formData.username) {
newErrors.username = 'Username is required';
}
if (!formData.email) {
newErrors.email = 'Email is required';
} else if (!/\S+@\S+\.\S+/.test(formData.email)) {
newErrors.email = 'Email address is invalid';
}
if (!formData.password) {
newErrors.password = 'Password is required';
} else if (formData.password.length < 6) {
newErrors.password = 'Password must be at least 6 characters';
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0; // returns true if no errors
};
const handleSubmit = (e) => {
e.preventDefault();
if (validate()) {
alert('Form is valid!');
// Proceed with form submission logic here (e.g., API call)
} else {
alert('Please fix the errors');
}
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>Username</label>
<input
type="text"
name="username"
value={formData.username}
onChange={handleChange}
/>
{errors.username && <div style={{ color: 'red' }}>{errors.username}</div>}
</div>
<div>
<label>Email</label>
<input
type="email"
name="email"
value={formData.email}
onChange={handleChange}
/>
{errors.email && <div style={{ color: 'red' }}>{errors.email}</div>}
</div>
<div>
<label>Password</label>
<input
type="password"
name="password"
value={formData.password}
onChange={handleChange}
/>
{errors.password && <div style={{ color: 'red' }}>{errors.password}</div>}
</div>
<button type="submit">Submit</button>
</form>
);
}
export default MyForm;
Review:
- State Management: We manage form data using the
formData
state, and error messages usingerrors
. - Validation: The
validate
function checks if the form fields are filled correctly (e.g., non-empty, valid email format). - Error Handling: If validation fails, it sets error messages for the fields, and these errors are displayed beneath the corresponding input fields.
2. Using Form Validation Libraries (e.g., Formik)
For more complex forms, handling validation with plain React can become cumbersome. In such cases, using a library like Formik can simplify form handling.
Formik with Yup for Validation
- Install Formik and Yup:
#bash
npm install formik yup
2. Formik + Yup Exercise:
#reactjs
import React from 'react';
import { useFormik } from 'formik';
import * as Yup from 'yup';
function MyForm() {
const formik = useFormik({
initialValues: {
username: '',
email: '',
password: ''
},
validationSchema: Yup.object({
username: Yup.string().required('Username is required'),
email: Yup.string().email('Invalid email address').required('Email is required'),
password: Yup.string()
.min(6, 'Password must be at least 6 characters')
.required('Password is required')
}),
onSubmit: (values) => {
alert('Form submitted successfully');
console.log(values);
}
});
return (
<form onSubmit={formik.handleSubmit}>
<div>
<label>Username</label>
<input
type="text"
name="username"
value={formik.values.username}
onChange={formik.handleChange}
/>
{formik.touched.username && formik.errors.username ? (
<div style={{ color: 'red' }}>{formik.errors.username}</div>
) : null}
</div>
<div>
<label>Email</label>
<input
type="email"
name="email"
value={formik.values.email}
onChange={formik.handleChange}
/>
{formik.touched.email && formik.errors.email ? (
<div style={{ color: 'red' }}>{formik.errors.email}</div>
) : null}
</div>
<div>
<label>Password</label>
<input
type="password"
name="password"
value={formik.values.password}
onChange={formik.handleChange}
/>
{formik.touched.password && formik.errors.password ? (
<div style={{ color: 'red' }}>{formik.errors.password}</div>
) : null}
</div>
<button type="submit">Submit</button>
</form>
);
}
export default MyForm;
Review:
- Formik: This library helps manage form state, handle submission, and track touched fields (which are useful for validation error display).
- Yup: A validation schema library that allows for easy and readable validation rules. Here, we’re using
Yup.string().required()
,.email()
, and.min()
to validate the fields. - Error Display: Formik provides an easy way to check if a field is “touched” and if there is an error for that field. This ensures that validation messages only appear after the user interacts with the field.
3. Using React Hook Form (Another Popular Library)
Another great alternative is React Hook Form, which is known for being lightweight and performing better in complex forms.
Exercise with React Hook Form:
- Install React Hook Form:
#bash
npm install react-hook-form
2. Exercise Code:
#reactjs
import React from 'react';
import { useForm } from 'react-hook-form';
function MyForm() {
const {
register,
handleSubmit,
formState: { errors }
} = useForm();
const onSubmit = (data) => {
alert('Form submitted successfully');
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label>Username</label>
<input
type="text"
{...register('username', { required: 'Username is required' })}
/>
{errors.username && <div style={{ color: 'red' }}>{errors.username.message}</div>}
</div>
<div>
<label>Email</label>
<input
type="email"
{...register('email', {
required: 'Email is required',
pattern: {
value: /\S+@\S+\.\S+/,
message: 'Invalid email address'
}
})}
/>
{errors.email && <div style={{ color: 'red' }}>{errors.email.message}</div>}
</div>
<div>
<label>Password</label>
<input
type="password"
{...register('password', {
required: 'Password is required',
minLength: { value: 6, message: 'Password must be at least 6 characters' }
})}
/>
{errors.password && <div style={{ color: 'red' }}>{errors.password.message}</div>}
</div>
<button type="submit">Submit</button>
</form>
);
}
export default MyForm;
Review:
- React Hook Form: This library makes form handling much easier by using hooks. It automatically tracks the form state and manages form submission.
- Validation: The
register
function accepts validation rules likerequired
,pattern
, andminLength
. - Error Handling: Errors are handled automatically via
formState.errors
, and we display messages accordingly.
Note:
- For simple forms, you can manually handle validation with
useState
and conditional rendering. - For larger forms, consider using libraries like Formik or React Hook Form, which simplify form handling and validation, especially when combined with Yup for schema-based validation.
Each method has its pros and cons, so you can choose based on the complexity of your form and your preference for working with external libraries.
Understanding How Coding Filters Help Reduce Complexity!
Coding filters offer a powerful way to reduce complexity by providing a mechanism to focus on relevant data or logic while ignoring unnecessary elements. By applying these filters, developers can avoid convoluted conditional statements, reducing code length and enhancing clarity in their applications.