Skip to main content

Form Validation: The Basics - Simple Client-Side Validation Techniques #76

📖 Introduction

Following our exploration of Uncontrolled Components and useRef, this article focuses on a crucial aspect of form handling: client-side validation. We will learn the basic techniques for validating user input in React, ensuring data integrity and improving the user experience.


📚 Prerequisites

Before we begin, please ensure you have a solid grasp of the following concepts:

  • Controlled Components
  • React state management with the useState hook
  • Basic JavaScript conditional logic (if/else, ternary operators)

🎯 Article Outline: What You'll Master

In this article, you will learn:

  • Foundational Theory: The importance of client-side validation and the different types of validation rules.
  • Core Implementation: How to implement basic validation for required fields, length constraints, and pattern matching.
  • Practical Application: Building a simple registration form with real-time validation feedback.
  • Best Practices: How to structure your validation logic for clarity and maintainability.

🧠 Section 1: The Core Concepts of Form Validation

Client-side validation is the process of checking user input in the browser before it is sent to the server. This provides immediate feedback to the user, creating a much better user experience than server-side validation alone.

Common Validation Rules:

  • Presence: Ensuring a field is not empty.
  • Length: Checking for a minimum or maximum number of characters.
  • Format: Using regular expressions to validate specific patterns (e.g., email addresses, phone numbers).
  • Inclusion/Exclusion: Ensuring a value is within a specific set of options.

💻 Section 2: Deep Dive - Implementation and Walkthrough

Let's build a simple registration form with validation.

2.1 - Setting Up the State

First, we need to set up our state to hold the form values and any validation errors.

// code-block-1.jsx
import React, { useState } from 'react';

function RegistrationForm() {
const [values, setValues] = useState({
username: '',
email: '',
password: '',
});

const [errors, setErrors] = useState({});

// ...
}

2.2 - Implementing the Validation Logic

We'll create a validate function that takes the form values and returns an object with any errors.

// code-block-2.jsx
const validate = (name, value) => {
switch (name) {
case 'username':
if (!value) {
return 'Username is required';
}
break;
case 'email':
if (!value) {
return 'Email is required';
}
if (!/\S+@\S+\.\S+/.test(value)) {
return 'Email is not valid';
}
break;
case 'password':
if (!value) {
return 'Password is required';
}
if (value.length < 6) {
return 'Password must be at least 6 characters';
}
break;
default:
break;
}
};

2.3 - The handleChange Function with Real-Time Validation

Now, let's modify our handleChange function to perform validation every time the user types.

// code-block-3.jsx
const handleChange = (event) => {
const { name, value } = event.target;
setValues(prevValues => ({
...prevValues,
[name]: value,
}));

const error = validate(name, value);
setErrors(prevErrors => ({
...prevErrors,
[name]: error,
}));
};

2.4 - Rendering the Form and Displaying Errors

Now, let's render the form and display any validation errors.

// code-block-4.jsx
return (
<form>
<div>
<label>Username:</label>
<input
type="text"
name="username"
value={values.username}
onChange={handleChange}
/>
{errors.username && <p style={{ color: 'red' }}>{errors.username}</p>}
</div>
<div>
<label>Email:</label>
<input
type="email"
name="email"
value={values.email}
onChange={handleChange}
/>
{errors.email && <p style={{ color: 'red' }}>{errors.email}</p>}
</div>
<div>
<label>Password:</label>
<input
type="password"
name="password"
value={values.password}
onChange={handleChange}
/>
{errors.password && <p style={{ color: 'red' }}>{errors.password}</p>}
</div>
<button type="submit">Submit</button>
</form>
);

🛠️ Section 3: Handling Form Submission

Now, let's handle the form submission. We only want to allow the form to be submitted if there are no errors.

// code-block-5.jsx
const handleSubmit = (event) => {
event.preventDefault();
const hasErrors = Object.values(errors).some(error => error);
if (!hasErrors) {
console.log('Form submitted:', values);
alert('Form submitted successfully!');
} else {
alert('Please fix the errors before submitting.');
}
};

// ... in the return statement
<form onSubmit={handleSubmit}>
{/* ... form fields ... */}
</form>

We can also disable the submit button if there are any errors.

// code-block-6.jsx
const hasErrors = Object.values(errors).some(error => error);

// ... in the return statement
<button type="submit" disabled={hasErrors}>
Submit
</button>

✨ Section 4: Best Practices

  • Provide clear and concise error messages: Help the user understand what they need to fix.
  • Validate on change and on blur: For a better user experience, you can validate on the onChange event for immediate feedback, and also on the onBlur event (when the user clicks out of the input).
  • Don't rely on client-side validation alone: Always validate on the server-side as well, as client-side validation can be bypassed.
  • Consider using a form library for complex forms: For forms with complex validation logic, libraries like Formik or React Hook Form can save you a lot of time and effort.

💡 Conclusion & Key Takeaways

Congratulations! You've learned the basics of client-side form validation in React. You can now provide immediate feedback to your users, improving the user experience and ensuring data integrity.

Let's summarize the key takeaways:

  • Client-side validation provides immediate feedback to the user.
  • Validation logic can be implemented in a separate function for clarity and reusability.
  • Real-time validation can be achieved by calling the validation function in the handleChange handler.
  • Always validate on the server-side as well.

Challenge Yourself: To solidify your understanding, try to add a "confirm password" field to the form with validation to ensure it matches the password field.


➡️ Next Steps

You now have a solid foundation in basic form validation. In the next article, "Advanced Form Handling with Formik (Part 1)", we will explore how to use a popular form library to simplify and streamline our form handling and validation logic.

Thank you for your dedication. Stay curious, and happy coding!


glossary

  • Client-Side Validation: The process of validating user input in the browser.
  • Regular Expression (Regex): A sequence of characters that defines a search pattern.
  • onBlur: An event that fires when an element has lost focus.

Further Reading