Forms and User Input in React
Introduction
In the previous chapter, you learned how to control what appears on the screen using conditional rendering and how to display data using lists. Now, we move to a very practical topic — handling forms and user input.
Forms are essential in almost every web application. Users enter names, emails, passwords, search queries, and more. React provides a structured way to manage this input using state, making forms predictable and easy to control.
What Are Controlled Components?
In React, form elements such as input, textarea, and select are usually handled as controlled components. This means the form data is controlled by React state.
Instead of the DOM managing the input’s value, React keeps the value in state and updates it whenever the user types.
import { useState } from "react";
function NameForm() {
const [name, setName] = useState("");
return (
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
);
}
Here, the input always displays the value stored in state.
Handling Form Submission
When a form is submitted, the browser normally reloads the page. In React, we prevent this using e.preventDefault().
function FormExample() {
const [email, setEmail] = useState("");
function handleSubmit(e) {
e.preventDefault();
alert(`Submitted: ${email}`);
}
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<button type="submit">Submit</button>
</form>
);
}
React handles the submission logic without refreshing the page.
Handling Multiple Inputs
Forms often contain multiple fields. You can store them in separate state variables or in a single state object.
function SignupForm() {
const [formData, setFormData] = useState({ name: "", password: "" });
function handleChange(e) {
setFormData({ ...formData, [e.target.name]: e.target.value });
}
return (
<form>
<input name="name" value={formData.name} onChange={handleChange} />
<input name="password" type="password" value={formData.password} onChange={handleChange} />
</form>
);
}
The name attribute helps identify which field is being updated.
Working with Textarea and Select
React handles textarea and select similarly to input.
function FeedbackForm() {
const [message, setMessage] = useState("");
const [role, setRole] = useState("user");
return (
<form>
<textarea value={message} onChange={(e) => setMessage(e.target.value)} />
<select value={role} onChange={(e) => setRole(e.target.value)}>
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
</form>
);
}
Both elements are controlled through state.
Basic Form Validation
You can validate inputs before submitting.
function LoginForm() {
const [username, setUsername] = useState("");
function handleSubmit(e) {
e.preventDefault();
if (username.trim() === "") {
alert("Username is required");
return;
}
alert("Login successful");
}
return (
<form onSubmit={handleSubmit}>
<input value={username} onChange={(e) => setUsername(e.target.value)} />
<button type="submit">Login</button>
</form>
);
}
Validation ensures correct data before processing.
Controlled vs Uncontrolled Components
Controlled components use React state, while uncontrolled components rely on the DOM to manage values using refs.
Controlled components are preferred because they provide better control and validation.
Common Mistakes to Avoid
Forgetting to use the value with the state
Not using onChange with inputs
Forgetting e.preventDefault() on form submit
Mutating form state directly instead of using setState
Summary
In this chapter, you learned how React handles forms using controlled components. You managed input fields with state, handled form submissions, worked with multiple inputs, used textarea and select, and performed basic validation. Forms are now fully manageable using React’s state system.