Technical FAQ for Developers
Find answers for the most frequently asked questions
When dealing with forms in a React app, validation is key. It ensures user data, such as email formats and required fields, meets the necessary criteria before being processed, improving both security and user experience.
Form validation can be performed either on the client side or the server side. However, for comprehensive validation, it is often essential to implement checks on both fronts.
Validation that occurs in the browser, providing instant feedback. Enhances user experience but must not be the only line of defense.
Validation that occurs after the form is submitted to the server. Critical for security to catch tampered or malicious inputs.
A combination of both methods is recommended.
Basic client-side validation can be done by writing simple custom functions, which gives us complete control over our validation rules.
import React, { useState } from "react";
function LoginForm() {
const [formData, setFormData] = useState({
email: "",
password: "",
});
const [errors, setErrors] = useState({});
// Handle input changes
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prevData) => ({
...prevData,
[name]: value,
}));
// Clear error when field is edited
if (errors[name]) {
setErrors({
...errors,
[name]: null,
});
}
};
// Validate all form fields
const validateForm = () => {
const newErrors = {};
// Email validation
if (!formData.email) {
newErrors.email = "Email is required";
} else if (!/\S+@\S+\.\S+/.test(formData.email)) {
newErrors.email = "Email address is invalid";
}
// Password validation
if (!formData.password) {
newErrors.password = "Password is required";
} else if (formData.password.length < 8) {
newErrors.password = "Password must be at least 8 characters";
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = (e) => {
e.preventDefault();
if (validateForm()) {
// Submit form data
console.log("Form submitted:", formData);
}
};
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="email">Email</label>
<input
// type="email"
id="email"
name="email"
value={formData.email}
onChange={handleChange}
/>
{errors.email && <p className="error">{errors.email}</p>}
</div>
<div>
<label htmlFor="password">Password</label>
<input
type="password"
id="password"
name="password"
value={formData.password}
onChange={handleChange}
/>
{errors.password && <p className="error">{errors.password}</p>}
</div>
<button type="submit">Login</button>
</form>
);
}
export default LoginForm;
When users interact with the above form, they enter data into the fields, and upon submission, validateForm checks each field. If errors are found, they're displayed below the relevant inputs, and the form is only submitted if all validations pass.
For more complex validation scenarios, specialized libraries can save development time. React Hook Form is a popular library that is performant, flexible and makes it simple to create forms with validation.
React Hook Form is built on uncontrolled components, reducing unnecessary re-renders while providing a comprehensive validation API. It uses a hook-based approach to manage form state and validation.
Let's implement the same login form we saw above using React Hook Form:
import React from "react";
import { useForm } from "react-hook-form";
function LoginForm() {
// Initialize React Hook Form
const {
register, // Function to register inputs
handleSubmit, // Form submission handler
formState: { errors }, // Form error state
} = useForm();
// Form submission handler
const onSubmit = (data) => {
console.log("Form submitted:", data);
};
return (
{errors.email && (
{errors.email.message}
)}
{errors.password && (
{errors.password.message}
)}
);
}
export default LoginForm;
In this example, the register function connects inputs to the form, validation rules are defined inline with each field, React Hook Form handles all validation logic, and errors are displayed using the errors object from formState.
React Hook Form offers several advantages, including better performance through fewer re-renders, built-in validation, easy integration with UI libraries, support for complex form structures and reduced boilerplate code.
KendoReact also provides extensive validation capabilities, both at the field and form level. Below is an equivalent login form using KendoReact's built-in validation system:
import * as React from "react"; import { Form, Field, FormElement } from "@progress/kendo-react-form"; import { Input } from "@progress/kendo-react-inputs"; import { Error } from "@progress/kendo-react-labels"; import { Button } from "@progress/kendo-react-buttons"; const requiredValidator = (value) => value ? undefined : "This field is required"; const emailValidator = (value) => /\\S+@\\S+\\.\\S+/.test(value) ? undefined : "Invalid email format"; const CustomInput = ({ validationMessage, visited, label, ...props }) => (
{visited && validationMessage &&); const KendoLoginForm = () => ({validationMessage} }console.log("Form submitted:", data)} render={(formRenderProps) => (
)} /> ); export default KendoLoginForm;
This implementation of KendoReact validation demonstrates its extensive capabilities for managing form state and verifying data accuracy. The <Form />
and <Field />
components define the structure, while validation functions enforce required fields and email formatting. The <CustomInput />
component integrates error messages, and, when the form is submitted, validated data is captured and logged to the console.
In the previous sections, we primarily explored field-level validation, where errors are displayed directly beneath individual form inputs. Another crucial aspect of form validation is form-level error handling. This approach helps present broader issues—such as incorrect login credentials, server validation failures, or multiple field errors—in a user-friendly way.
KendoReact provides built-in validation capabilities at both the field and form levels. Below is an example of how we can implement form-level validation in a login form using the KendoReact Form and Field components:
import * as React from "react";
import {
Form,
Field,
FormElement,
FormRenderProps,
} from "@progress/kendo-react-form";
import { Input } from "@progress/kendo-react-inputs";
import { Button } from "@progress/kendo-react-buttons";
import { Error } from "@progress/kendo-react-labels";
import { getter } from "@progress/kendo-react-common";
// Validators
const emailValidator = (value) =>
!value
? "Email is required"
: /\\S+@\\S+\\.\\S+/.test(value)
? undefined
: "Email is invalid";
const passwordValidator = (value) =>
!value
? "Password is required"
: value.length < 8
? "Password must be at least 8 characters"
: undefined;
// Utility getter for form-level validation
const emailGetter = getter("email");
const passwordGetter = getter("password");
const formValidator = (values) => {
if (emailGetter(values) && passwordGetter(values)) {
return;
}
return {
VALIDATION_SUMMARY: "Please fill in both the email and password fields.",
email: "Please check the validation summary for more details.",
password: "Please check the validation summary for more details.",
};
};
const ValidatedInput = (fieldRenderProps) => {
const { validationMessage, visited, ...others } = fieldRenderProps;
return (
{visited && validationMessage && {validationMessage} }
);
};
const LoginForm = () => {
const handleSubmit = (data) => {
console.log("Form submitted successfully", data);
};
return (
(
{formRenderProps.visited &&
formRenderProps.errors &&
formRenderProps.errors.VALIDATION_SUMMARY && (
{formRenderProps.errors.VALIDATION_SUMMARY}
)}
)}
/>
);
};
export default LoginForm;
In this implementation, we use the KendoReact Form and Field components to handle validation efficiently. Each field has a corresponding validation function (emailValidator and passwordValidator), verifying user inputs meet the required criteria. If validation fails, error messages appear below the corresponding inputs.
We also implement a form-level validation function formValidator, which checks whether both email and password fields are filled in. If either field is missing, an overarching error message (VALIDATION_SUMMARY) is displayed at the top of the form. This provides users guidance on what needs to be corrected before submitting.
If you haven't yet, check out the comprehensive React Forms FAQ to learn all about creating, managing and optimizing forms in React applications.