βοΈ Introduction
Forms are one of the most essential parts of any web application β from login pages to contact forms and checkout screens.
But managing form inputs, tracking user data, and validating it efficiently can be tricky. π
Luckily, React provides simple yet powerful tools to handle forms and validation in a clean, declarative way.
In this article, weβll explore:
β
How to handle form inputs in React
β
Controlled vs Uncontrolled Components
β
Validation techniques (manual & library-based)
β
Practical examples and best practices
Letβs dive in! π
π§Ύ 1. Forms in React β The Basics
In traditional HTML, form elements like <input>, <textarea>, and <select> maintain their own internal state.
But in React, state should be controlled by components β thatβs where controlled components come in.
ποΈ 2. Controlled Components
A controlled component means the form data is handled by the React componentβs state instead of the DOM.
Example π
import React, { useState } from "react";
function SimpleForm() {
const [name, setName] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
alert(`Hello, ${name}!`);
};
return (
<form onSubmit={handleSubmit}>
<label>Enter your name:</label><br />
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<button type="submit">Submit</button>
</form>
);
}
π§ How It Works
The value of the input is linked to Reactβs state (name).
Every keystroke triggers onChange, updating the state.
When submitted, you can access name directly from the component.
β
Benefits
πͺ 3. Uncontrolled Components
In uncontrolled components, form data is handled by the DOM itself β not React state.
You access values using refs.
Example π
import React, { useRef } from "react";
function UncontrolledForm() {
const inputRef = useRef();
const handleSubmit = (e) => {
e.preventDefault();
alert(`Hello, ${inputRef.current.value}!`);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={inputRef} />
<button type="submit">Submit</button>
</form>
);
}
β
Simpler for quick forms
β οΈ But harder to validate and debug β thatβs why most React apps use controlled components.
β
4. Handling Multiple Inputs
If you have several fields, you can manage them in one state object.
Hereβs an example with name and email π
import React, { useState } from "react";
function MultiInputForm() {
const [formData, setFormData] = useState({
name: "",
email: "",
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prev) => ({
...prev,
[name]: value,
}));
};
const handleSubmit = (e) => {
e.preventDefault();
console.log(formData);
};
return (
<form onSubmit={handleSubmit}>
<label>Name:</label>
<input name="name" value={formData.name} onChange={handleChange} />
<br />
<label>Email:</label>
<input name="email" value={formData.email} onChange={handleChange} />
<br />
<button type="submit">Submit</button>
</form>
);
}
π― This approach scales easily when your form grows.
π§© 5. Form Validation β Why It Matters
Form validation ensures users enter correct and complete data before submission.
React offers two main ways to validate forms:
Manual Validation (using custom logic)
Library-Based Validation (using tools like Formik or React Hook Form)
Letβs look at both π
π 6. Manual Validation
You can validate fields before submission with simple JavaScript checks.
Example π
function SignupForm() {
const [email, setEmail] = useState("");
const [error, setError] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
if (!email.includes("@")) {
setError("Please enter a valid email.");
} else {
setError("");
alert("Form submitted successfully!");
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="email"
placeholder="Enter email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
{error && <p style={{ color: "red" }}>{error}</p>}
<button type="submit">Submit</button>
</form>
);
}
π§ This approach gives full control β but can get messy with large forms.
βοΈ 7. Form Validation with Libraries
For complex forms (multiple fields, error messages, etc.), libraries like Formik or React Hook Form make validation simple and elegant.
π Example using React Hook Form
npm install react-hook-form
Then use it in your component π
import React from "react";
import { useForm } from "react-hook-form";
function RHFForm() {
const {
register,
handleSubmit,
formState: { errors },
} = useForm();
const onSubmit = (data) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input
{...register("email", {
required: "Email is required",
pattern: {
value: /^\S+@\S+$/i,
message: "Invalid email format",
},
})}
placeholder="Enter email"
/>
{errors.email && <p>{errors.email.message}</p>}
<button type="submit">Submit</button>
</form>
);
}
π Advantages of React Hook Form:
π 8. Common Form Best Practices
β
Always prevent default form submission using e.preventDefault()
β
Use controlled components for better control
β
Provide clear error messages and visual feedback
β
Use autoFocus and required attributes where needed
β
Sanitize user input to prevent security issues
β
Consider form libraries for large or dynamic forms
π§ 9. Controlled vs Uncontrolled Summary
Feature Controlled Uncontrolled
State Managed by React Managed by DOM
Validation Easy Harder
Performance Slightly slower Faster (small forms)
Use Case: Most React forms are Simple, quick forms
π‘ 10. Wrapping Up
Handling forms and validation in React might seem challenging at first,
but once you understand state management, controlled components, and validation logic,
it becomes super intuitive πͺ
React gives you the flexibility to:
Build a custom form
Or use battle-tested libraries for large projects π
Whether itβs a simple contact form or a full registration system β React makes it elegant, powerful, and scalable. βοΈπ«