1. Forms in React & Handling Input
In standard HTML, form elements like <input> and <textarea> manage their own internal DOM state. In React, we bridge this by connecting inputs directly to React component state.
onChange Fires ➔ State Updates ➔ Component Re-renders ➔ Input displays new value.3. Controlled Components (value & onChange)
An input whose value is controlled by React state is called a Controlled Component. React state is the single source of truth:
export function SimpleInput() {
const [name, setName] = useState("");
return (
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter your name"
/>
);
}
4. Handling Multiple Inputs with One State Object
Instead of creating 10 different useState hooks, use a single composite object and dynamic computed property names:
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
};
5. Different Form Controls (Checkboxes, Selects, Textareas)
| Control Type | JSX Prop Binding | Value Extraction |
|---|---|---|
| Text / Email / Password | value={formData.email} | e.target.value |
| Checkbox | checked={formData.agreed} | e.target.checked (boolean) |
| Select Dropdown | value={formData.role} on <select> | e.target.value |
| Textarea | value={formData.bio} | e.target.value |
6. Form Submission & preventDefault()
e.preventDefault(); // Stop native browser page refresh
console.log("Submitting payload:", formData);
};
return <form onSubmit={handleSubmit}>...</form>;
7. Client-Side Form Validation & Error States
Validate input fields before sending requests over the network. Show clear inline error messages linked with accessible labels:
if (!formData.email.includes("@")) {
setErrors(prev => ({ ...prev, email: "Please enter a valid email address." }));
}
8. Managing Form State Lifecycles
Disable submit button and display a loading spinner while API request is in-flight.
Show a green toast or success confirmation screen and reset form values.
Display API error banners (e.g. "Email already registered") clearly.
9. Modern React Form Actions (<form action>)
In modern React (React 19 and Next.js Server Actions), you can pass an async function directly to the action prop of a form without writing manual onSubmit and e.preventDefault() boilerplate:
async function updateUser(formData) {
const name = formData.get("fullName");
await api.saveUser(name);
}
export function UserForm() {
return (
<form action={updateUser}>
<input name="fullName" defaultValue="Aarav" />
<button type="submit">Save</button>
</form>
);
}
10. Common Form Mistakes
- Initializing state to undefined: Triggers the warning "A component is changing an uncontrolled input to be controlled". Always initialize with
"". - Forgetting
e.preventDefault(): Causes the whole page to reload, losing all local React state. - Binding
valueinstead ofcheckedon checkboxes: Checkbox inputs requirechecked={bool}ande.target.checked. - Forgetting
nameattributes: Prevents generic[e.target.name]: valuehandlers from functioning.
11. React Forms Best Practices
- Always connect
<label htmlFor="id">with<input id="id">for accessibility. - Trim text inputs (
value.trim()) before validating. - Disable the submit button while an async submission is processing to prevent double-submits.